Skip to content

Commit 41a6cdf

Browse files
authored
Merge pull request #9 from slogsdon7/master
Read_only field style and tests
2 parents f62224f + 08be2cb commit 41a6cdf

File tree

3 files changed

+45
-3
lines changed

3 files changed

+45
-3
lines changed

mediafile.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ class StorageStyle(object):
450450
"""
451451

452452
def __init__(self, key, as_type=six.text_type, suffix=None,
453-
float_places=2):
453+
float_places=2, read_only=False):
454454
"""Create a basic storage strategy. Parameters:
455455
456456
- `key`: The key on the Mutagen file object used to access the
@@ -462,11 +462,16 @@ def __init__(self, key, as_type=six.text_type, suffix=None,
462462
- `float_places`: When the value is a floating-point number and
463463
encoded as a string, the number of digits to store after the
464464
decimal point.
465+
- `read_only`: When true, writing to this field is disabled.
466+
Primary use case is so wrongly named fields can be addressed
467+
in a graceful manner. This does not block the delete method.
468+
465469
"""
466470
self.key = key
467471
self.as_type = as_type
468472
self.suffix = suffix
469473
self.float_places = float_places
474+
self.read_only = read_only
470475

471476
# Convert suffix to correct string type.
472477
if self.suffix and self.as_type is six.text_type \
@@ -1198,7 +1203,8 @@ def __set__(self, mediafile, value):
11981203
if value is None:
11991204
value = self._none_value()
12001205
for style in self.styles(mediafile.mgfile):
1201-
style.set(mediafile.mgfile, value)
1206+
if not style.read_only:
1207+
style.set(mediafile.mgfile, value)
12021208

12031209
def __delete__(self, mediafile):
12041210
for style in self.styles(mediafile.mgfile):
@@ -1233,7 +1239,8 @@ def __get__(self, mediafile, _):
12331239

12341240
def __set__(self, mediafile, values):
12351241
for style in self.styles(mediafile.mgfile):
1236-
style.set_list(mediafile.mgfile, values)
1242+
if not style.read_only:
1243+
style.set_list(mediafile.mgfile, values)
12371244

12381245
def single_field(self):
12391246
"""Returns a ``MediaField`` descriptor that gets and sets the

test/rsrc/read_only_tag.m4a

5.72 KB
Binary file not shown.

test/test_mediafile_edge.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,41 @@ def test_image_encoding(self):
403403
self._delete_test()
404404

405405

406+
class ReadOnlyTagTest(unittest.TestCase, _common.TempDirMixin):
407+
def setUp(self):
408+
self.create_temp_dir()
409+
self.key = "READ_ONLY_TEST"
410+
self.field = mediafile.MediaField(
411+
mediafile.MP3StorageStyle(self.key, read_only=True),
412+
mediafile.MP4StorageStyle(
413+
"----:com.apple.iTunes:" + self.key, read_only=True),
414+
mediafile.StorageStyle(self.key, read_only=True),
415+
mediafile.ASFStorageStyle(self.key, read_only=True),
416+
)
417+
418+
if "read_only_test" not in mediafile.MediaFile.fields():
419+
mediafile.MediaFile.add_field("read_only_test", self.field)
420+
421+
def test_read(self):
422+
path = os.path.join(_common.RSRC, b'empty.flac')
423+
mf = mediafile.MediaFile(path)
424+
mf.mgfile.tags[self.key] = "don't"
425+
self.assertEqual("don't", mf.read_only_test)
426+
427+
def test_write(self):
428+
src = os.path.join(_common.RSRC, b'empty.flac')
429+
path = os.path.join(self.temp_dir, b'test.flac')
430+
shutil.copy(src, path)
431+
mf = mediafile.MediaFile(path)
432+
mf.read_only_field = "something terrible"
433+
mf.path = os.path.join(self.temp_dir, b'test.flac')
434+
mf.save()
435+
self.assertNotIn(self.key, mf.mgfile.tags)
436+
437+
def tearDown(self):
438+
self.remove_temp_dir()
439+
440+
406441
def suite():
407442
return unittest.TestLoader().loadTestsFromName(__name__)
408443

0 commit comments

Comments
 (0)