mirror of
https://github.com/beetbox/beets.git
synced 2025-12-27 11:02:43 +01:00
MPEG-4 Unicode freeform frames are now encoded as UTF-8 bytes
This commit is contained in:
parent
ec125b701f
commit
b63d6c858b
3 changed files with 33 additions and 4 deletions
|
|
@ -382,6 +382,11 @@ class MediaField(object):
|
|||
|
||||
if style.packing:
|
||||
out = Packed(out, style.packing)[style.pack_pos]
|
||||
|
||||
# MPEG-4 freeform frames are (should be?) encoded as UTF-8.
|
||||
if obj.type == 'mp4' and style.key.startswith('----:') and \
|
||||
isinstance(out, str):
|
||||
out = out.decode('utf8')
|
||||
|
||||
return _safe_cast(self.out_type, out)
|
||||
|
||||
|
|
@ -410,8 +415,8 @@ class MediaField(object):
|
|||
out = u''
|
||||
# We trust that packed values are handled above.
|
||||
|
||||
# convert to correct storage type (irrelevant for
|
||||
# packed values)
|
||||
# Convert to correct storage type (irrelevant for
|
||||
# packed values).
|
||||
if style.as_type == unicode:
|
||||
if out is None:
|
||||
out = u''
|
||||
|
|
@ -429,7 +434,13 @@ class MediaField(object):
|
|||
elif style.as_type in (bool, str):
|
||||
out = style.as_type(out)
|
||||
|
||||
# store the data
|
||||
# MPEG-4 "freeform" (----) frames must be encoded as UTF-8
|
||||
# byte strings.
|
||||
if obj.type == 'mp4' and style.key.startswith('----:') and \
|
||||
isinstance(out, unicode):
|
||||
out = out.encode('utf8')
|
||||
|
||||
# Store the data.
|
||||
self._storedata(obj, out, style)
|
||||
|
||||
class CompositeDateField(object):
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ CHAR_REPLACE = [
|
|||
(re.compile(r'[\\/\?]|^\.'), '_'),
|
||||
(re.compile(r':'), '-'),
|
||||
]
|
||||
CHAR_REPLACE_WINDOWS = re.compile('["\*<>\|]|^\.|\.$| +$'), '_'
|
||||
CHAR_REPLACE_WINDOWS = re.compile(r'["\*<>\|]|^\.|\.$| +$'), '_'
|
||||
def sanitize_path(path, pathmod=None):
|
||||
"""Takes a path and makes sure that it is legal. Returns a new path.
|
||||
Only works with fragments; won't work reliably on Windows when a
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
import unittest
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import _common
|
||||
import beets.mediafile
|
||||
|
|
@ -149,6 +150,23 @@ class SideEffectsTest(unittest.TestCase):
|
|||
new_mtime = os.stat(self.empty).st_mtime
|
||||
self.assertEqual(old_mtime, new_mtime)
|
||||
|
||||
class EncodingTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
src = os.path.join(_common.RSRC, 'full.m4a')
|
||||
self.path = os.path.join(_common.RSRC, 'test.m4a')
|
||||
shutil.copy(src, self.path)
|
||||
|
||||
self.mf = beets.mediafile.MediaFile(self.path)
|
||||
|
||||
def tearDown(self):
|
||||
os.remove(self.path)
|
||||
|
||||
def test_unicode_label_in_m4a(self):
|
||||
self.mf.label = u'foo\xe8bar'
|
||||
self.mf.save()
|
||||
new_mf = beets.mediafile.MediaFile(self.path)
|
||||
self.assertEqual(new_mf.label, u'foo\xe8bar')
|
||||
|
||||
def suite():
|
||||
return unittest.TestLoader().loadTestsFromName(__name__)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue