Merge branch 'release-2.0' into develop
This commit is contained in:
commit
c0ce188451
@ -58,6 +58,10 @@ Bug fix release.
|
|||||||
one. Particularly relevant for Mopidy-Scrobbler users, as before it was
|
one. Particularly relevant for Mopidy-Scrobbler users, as before it was
|
||||||
essentially unusable. (Fixes: :issue:`1456`, PR: :issue:`1534`)
|
essentially unusable. (Fixes: :issue:`1456`, PR: :issue:`1534`)
|
||||||
|
|
||||||
|
- Models: Fix encoding error if :class:`~mopidy.models.fields.Identifier`
|
||||||
|
fields, like the ``musicbrainz_id`` model fields, contained non-ASCII Unicode
|
||||||
|
data. (Fixes: :issue:`1508`, PR: :issue:`1546`)
|
||||||
|
|
||||||
- File: Ensure path comparison is done between bytestrings only. Fixes crash
|
- File: Ensure path comparison is done between bytestrings only. Fixes crash
|
||||||
where a :confval:`file/media_dirs` path contained non-ASCII characters.
|
where a :confval:`file/media_dirs` path contained non-ASCII characters.
|
||||||
(Fixes: :issue:`1345`, PR: :issue:`1493`)
|
(Fixes: :issue:`1345`, PR: :issue:`1493`)
|
||||||
@ -409,7 +413,7 @@ Bug fix release.
|
|||||||
proceed startup. (Fixes: :issue:`1248`, PR: :issue:`1254`)
|
proceed startup. (Fixes: :issue:`1248`, PR: :issue:`1254`)
|
||||||
|
|
||||||
- Stream: Fix bug in new playlist parser. A non-ASCII char in an urilist
|
- Stream: Fix bug in new playlist parser. A non-ASCII char in an urilist
|
||||||
comment would cause a crash while parsing due to comparision of a non-ASCII
|
comment would cause a crash while parsing due to comparison of a non-ASCII
|
||||||
bytestring with a Unicode string. (Fixes: :issue:`1265`)
|
bytestring with a Unicode string. (Fixes: :issue:`1265`)
|
||||||
|
|
||||||
- File: Adjust log levels when failing to expand ``$XDG_MUSIC_DIR`` into a real
|
- File: Adjust log levels when failing to expand ``$XDG_MUSIC_DIR`` into a real
|
||||||
|
|||||||
@ -31,10 +31,3 @@ accelerate requests to all Mopidy services, including:
|
|||||||
|
|
||||||
- https://dl.mopidy.com/pimusicbox/, which is used to distribute Pi Musicbox
|
- https://dl.mopidy.com/pimusicbox/, which is used to distribute Pi Musicbox
|
||||||
images.
|
images.
|
||||||
|
|
||||||
|
|
||||||
GlobalSign
|
|
||||||
==========
|
|
||||||
|
|
||||||
`GlobalSign <https://www.globalsign.com/>`_ provides Mopidy with a free SSL
|
|
||||||
certificate for mopidy.com, which we use to secure access to all our web sites.
|
|
||||||
|
|||||||
@ -136,12 +136,11 @@ def convert_tags_to_track(tags):
|
|||||||
return Track(**track_kwargs)
|
return Track(**track_kwargs)
|
||||||
|
|
||||||
|
|
||||||
def _artists(
|
def _artists(tags, artist_name, artist_id=None, artist_sortname=None):
|
||||||
tags, artist_name, artist_id=None, artist_sortname=None):
|
|
||||||
|
|
||||||
# Name missing, don't set artist
|
# Name missing, don't set artist
|
||||||
if not tags.get(artist_name):
|
if not tags.get(artist_name):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# One artist name and either id or sortname, include all available fields
|
# One artist name and either id or sortname, include all available fields
|
||||||
if len(tags[artist_name]) == 1 and \
|
if len(tags[artist_name]) == 1 and \
|
||||||
(artist_id in tags or artist_sortname in tags):
|
(artist_id in tags or artist_sortname in tags):
|
||||||
|
|||||||
@ -88,14 +88,17 @@ class Date(String):
|
|||||||
|
|
||||||
class Identifier(String):
|
class Identifier(String):
|
||||||
"""
|
"""
|
||||||
:class:`Field` for storing ASCII values such as GUIDs or other identifiers.
|
:class:`Field` for storing values such as GUIDs or other identifiers.
|
||||||
|
|
||||||
Values will be interned.
|
Values will be interned.
|
||||||
|
|
||||||
:param default: default value for field
|
:param default: default value for field
|
||||||
"""
|
"""
|
||||||
def validate(self, value):
|
def validate(self, value):
|
||||||
return compat.intern(str(super(Identifier, self).validate(value)))
|
value = super(Identifier, self).validate(value)
|
||||||
|
if isinstance(value, compat.text_type):
|
||||||
|
value = value.encode('utf-8')
|
||||||
|
return compat.intern(value)
|
||||||
|
|
||||||
|
|
||||||
class URI(Identifier):
|
class URI(Identifier):
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
# encoding: utf-8
|
||||||
|
|
||||||
from __future__ import absolute_import, unicode_literals
|
from __future__ import absolute_import, unicode_literals
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from mopidy.models.fields import Collection, Field, Integer, String
|
from mopidy.models.fields import Collection, Field, Identifier, Integer, String
|
||||||
|
|
||||||
|
|
||||||
def create_instance(field):
|
def create_instance(field):
|
||||||
@ -126,6 +128,42 @@ class StringTest(unittest.TestCase):
|
|||||||
self.assertEqual('', instance.attr)
|
self.assertEqual('', instance.attr)
|
||||||
|
|
||||||
|
|
||||||
|
class IdentifierTest(unittest.TestCase):
|
||||||
|
def test_default_handling(self):
|
||||||
|
instance = create_instance(Identifier(default='abc'))
|
||||||
|
self.assertEqual('abc', instance.attr)
|
||||||
|
|
||||||
|
def test_native_str_allowed(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
instance.attr = str('abc')
|
||||||
|
self.assertEqual('abc', instance.attr)
|
||||||
|
|
||||||
|
def test_bytes_allowed(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
instance.attr = b'abc'
|
||||||
|
self.assertEqual(b'abc', instance.attr)
|
||||||
|
|
||||||
|
def test_unicode_allowed(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
instance.attr = u'abc'
|
||||||
|
self.assertEqual(u'abc', instance.attr)
|
||||||
|
|
||||||
|
def test_unicode_with_nonascii_allowed(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
instance.attr = u'æøå'
|
||||||
|
self.assertEqual(u'æøå'.encode('utf-8'), instance.attr)
|
||||||
|
|
||||||
|
def test_other_disallowed(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
instance.attr = 1234
|
||||||
|
|
||||||
|
def test_empty_string(self):
|
||||||
|
instance = create_instance(Identifier())
|
||||||
|
instance.attr = ''
|
||||||
|
self.assertEqual('', instance.attr)
|
||||||
|
|
||||||
|
|
||||||
class IntegerTest(unittest.TestCase):
|
class IntegerTest(unittest.TestCase):
|
||||||
def test_default_handling(self):
|
def test_default_handling(self):
|
||||||
instance = create_instance(Integer(default=1234))
|
instance = create_instance(Integer(default=1234))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user