[Python-modules-commits] [mutagen] 01/07: Import mutagen_1.32.orig.tar.gz
Tristan Seligmann
mithrandi at moszumanska.debian.org
Sun May 22 07:45:46 UTC 2016
This is an automated email from the git hooks/post-receive script.
mithrandi pushed a commit to branch master
in repository mutagen.
commit d51dc5c78e408c3c152d4625a64d1c0ea6ff2bb1
Author: Tristan Seligmann <mithrandi at debian.org>
Date: Sun May 22 04:25:06 2016 +0200
Import mutagen_1.32.orig.tar.gz
---
NEWS | 25 ++++-
PKG-INFO | 4 +-
README.rst | 58 +-----------
docs/Makefile | 12 +--
docs/api/base.rst | 5 +
docs/api/index.rst | 2 +-
docs/api/smf.rst | 11 +++
docs/conf.py | 8 +-
docs/contact.rst | 10 ++
docs/ext.py | 10 +-
docs/index.rst | 67 ++++++--------
docs/man/index.rst | 27 +++++-
docs/tutorial.rst | 2 +-
mutagen/__init__.py | 6 +-
mutagen/_file.py | 8 +-
mutagen/_tags.py | 33 ++++++-
mutagen/_vorbis.py | 2 +-
mutagen/asf/__init__.py | 4 +-
mutagen/asf/_objects.py | 29 +++++-
mutagen/easymp4.py | 4 +-
mutagen/flac.py | 6 +-
mutagen/id3/__init__.py | 12 +--
mutagen/id3/_frames.py | 45 ++++++---
mutagen/id3/_specs.py | 17 +++-
mutagen/m4a.py | 4 +-
mutagen/mp4/__init__.py | 79 +++++++++-------
mutagen/smf.py | 203 +++++++++++++++++++++++++++++++++++++++++
setup.py | 2 +-
tests/data/sample.mid | Bin 0 -> 8444 bytes
tests/quality/test_pep8.py | 2 +-
tests/quality/test_pyflakes.py | 3 +-
tests/test___init__.py | 4 +
tests/test__id3frames.py | 36 +++++++-
tests/test__id3specs.py | 9 +-
tests/test_aiff.py | 2 +
tests/test_apev2.py | 4 +-
tests/test_asf.py | 22 ++++-
tests/test_easyid3.py | 4 +-
tests/test_flac.py | 4 +-
tests/test_id3.py | 53 ++++++-----
tests/test_mp3.py | 2 +-
tests/test_mp4.py | 17 ++--
tests/test_musepack.py | 2 +-
tests/test_ogg.py | 2 +-
tests/test_smf.py | 27 ++++++
45 files changed, 643 insertions(+), 245 deletions(-)
diff --git a/NEWS b/NEWS
index 99faafc..cb4960a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,22 @@
+1.32 - 2016.05.02
+-----------------
+
+* Add basic SMF (Standard MIDI File) support (:mod:`mutagen.smf`)
+* FLAC: add ``audio/flac`` mime type. :bug:`235`
+* ASF: Fixed crash when object size is longer than the header and file length
+ (Ben Ockmore)
+* ID3: Validate attributes set after frame creation :bb-pr:`8`
+ (Daniel Plachotich)
+* MP4: validate values in ``__setitem__`` so things don't fail in save()
+ :bug:`236`
+* tests: Fix SynchronizedTextSpec test on big-endian machines :bug:`247`
+ (Daniel Plachotich)
+* ID3: do type checking in ``__setitem__`` :bug:`251`
+* Building the documentation now requires sphinx >= 1.3
+* New :class:`mutagen.Tags` base class for tags
+* Moved from Bitbucket to GitHub
+
+
1.31 - 2015.09.10
-----------------
@@ -96,7 +115,7 @@
* MP4:
* New ``MP4Info.codec`` for identifying the contained audio codec
- e.g. ``"mp4a"``, ``"alac"``, ``"mp4a.40.2"``, ``"ac-3"`` etc. :pr:`6`
+ e.g. ``"mp4a"``, ``"alac"``, ``"mp4a.40.2"``, ``"ac-3"`` etc. :bb-pr:`6`
* New ``MP4Info.codec_description``: name of the audio codec
e.g. ``"ALAC"``, ``"AAC LC"``, ``"AC-3"``
@@ -117,7 +136,7 @@
* MP4:
* Parse channels/sample_rate/bits_per_sample/bitrate for ALAC files
- :bug:`199` :pr:`5` (Adrian Sampson, Christoph Reiter)
+ :bug:`199` :bb-pr:`5` (Adrian Sampson, Christoph Reiter)
* ASF:
@@ -132,7 +151,7 @@
* docs:
- * New logo :pr:`4` (Samuel Messner)
+ * New logo :bb-pr:`4` (Samuel Messner)
* Add examples for handling cover art in vorbiscomment :bug:`200`
* Add examples for id3v2.3
diff --git a/PKG-INFO b/PKG-INFO
index 306b01c..4594950 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,8 +1,8 @@
Metadata-Version: 1.1
Name: mutagen
-Version: 1.31
+Version: 1.32
Summary: read and write audio tags for many formats
-Home-page: https://bitbucket.org/lazka/mutagen
+Home-page: https://github.com/quodlibet/mutagen
Author: Michael Urman
Author-email: quod-libet-development at groups.google.com
License: GNU GPL v2
diff --git a/README.rst b/README.rst
index 7ea1b21..1affc6a 100644
--- a/README.rst
+++ b/README.rst
@@ -1,58 +1,8 @@
Mutagen
=======
-Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC,
-M4A, Monkey's Audio, MP3, Musepack, Ogg Opus, Ogg FLAC, Ogg Speex, Ogg
-Theora, Ogg Vorbis, True Audio, WavPack, OptimFROG, and AIFF audio files.
-All versions of ID3v2 are supported, and all standard ID3v2.4 frames are
-parsed. It can read Xing headers to accurately calculate the bitrate and
-length of MP3s. ID3 and APEv2 tags can be edited regardless of audio
-format. It can also manipulate Ogg streams on an individual packet/page
-level.
+Mutagen is a Python module to handle audio metadata. For more information
+visit http://mutagen.readthedocs.org
-Mutagen works on Python 2.6, 2.7, 3.3, 3.4 (CPython and PyPy) and has no
-dependencies outside the Python standard library.
-
-
-Installing
-----------
-
- $ ./setup.py build
- $ su -c "./setup.py install"
-
-
-Documentation
--------------
-
-The primary documentation for Mutagen is the doc strings found in
-the source code and the sphinx documentation in the docs/ directory.
-
-To build the docs (needs sphinx):
-
- $ ./setup.py build_sphinx
-
-The tools/ directory contains several useful examples.
-
-The docs are also hosted on readthedocs.org:
-
- http://mutagen.readthedocs.org
-
-
-Testing the Module
-------------------
-
-To test Mutagen's MP3 reading support, run
- $ tools/mutagen-pony <your top-level MP3 directory here>
-Mutagen will try to load all of them, and report any errors.
-
-To look at the tags in files, run
- $ tools/mutagen-inspect filename ...
-
-To run our test suite,
- $ ./setup.py test
-
-
-Compatibility/Bugs
-------------------
-
-See docs/bugs.rst
+.. image:: https://travis-ci.org/quodlibet/mutagen.svg?branch=master
+ :target: https://travis-ci.org/quodlibet/mutagen
diff --git a/docs/Makefile b/docs/Makefile
index 473139b..3720e52 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -1,13 +1,7 @@
-all: _rtd_theme
- sphinx-build -E -Dhtml_theme=_rtd_theme -Dhtml_theme_path=. -b html -n . _build
+all:
+ sphinx-build -E -b html -n . _build
clean:
- rm -rf _build _rtd_theme
+ rm -rf _build
.PHONY: clean
-
-_rtd_theme:
- wget https://github.com/snide/sphinx_rtd_theme/archive/master.tar.gz
- tar --strip-components=1 -zxvf master.tar.gz sphinx_rtd_theme-master/sphinx_rtd_theme
- mv sphinx_rtd_theme _rtd_theme
- rm master.tar.gz
diff --git a/docs/api/base.rst b/docs/api/base.rst
index b714f81..b7f9cb7 100644
--- a/docs/api/base.rst
+++ b/docs/api/base.rst
@@ -23,6 +23,11 @@ Base Classes
.. automethod:: save()
+.. autoclass:: mutagen.Tags
+
+ .. automethod:: pprint()
+
+
.. autoclass:: mutagen.Metadata
.. automethod:: delete()
diff --git a/docs/api/index.rst b/docs/api/index.rst
index d98368d..c4a0976 100644
--- a/docs/api/index.rst
+++ b/docs/api/index.rst
@@ -21,7 +21,7 @@ API
oggtheora
oggvorbis
optimfrog
+ smf
trueaudio
vcomment
wavpack
-
diff --git a/docs/api/smf.rst b/docs/api/smf.rst
new file mode 100644
index 0000000..6abd86c
--- /dev/null
+++ b/docs/api/smf.rst
@@ -0,0 +1,11 @@
+Standard MIDI File
+==================
+
+.. automodule:: mutagen.smf
+
+.. autoclass:: mutagen.smf.SMF(filename)
+ :show-inheritance:
+ :members:
+
+.. autoclass:: mutagen.smf.SMFInfo()
+ :members:
diff --git a/docs/conf.py b/docs/conf.py
index 10ceb0d..554fab6 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -8,6 +8,7 @@ sys.path.insert(0, dir_)
sys.path.insert(0, os.path.abspath(os.path.join(dir_, "..")))
import mutagen
+needs_sphinx = "1.3"
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'ext']
intersphinx_mapping = {'python': ('http://docs.python.org/2.7', None)}
@@ -19,8 +20,11 @@ copyright = u'2014, Joe Wreschnig, Michael Urman, Lukáš Lalinský, ' \
version = mutagen.version_string
release = mutagen.version_string
exclude_patterns = ['_build']
-bug_url_template = "http://bitbucket.org/lazka/mutagen/issue/%s"
-pr_url_template = "http://bitbucket.org/lazka/mutagen/pull-request/%s"
+bug_url_template = "https://github.com/quodlibet/mutagen/issues/%s"
+pr_url_template = "https://github.com/quodlibet/mutagen/pull/%s"
+bbpr_url_template = "https://bitbucket.org/lazka/mutagen/pull-requests/%s"
autodoc_member_order = "bysource"
default_role = "obj"
+
+html_theme = "sphinx_rtd_theme"
diff --git a/docs/contact.rst b/docs/contact.rst
new file mode 100644
index 0000000..25931ca
--- /dev/null
+++ b/docs/contact.rst
@@ -0,0 +1,10 @@
+Contact
+-------
+
+For historical and practical reasons, Mutagen shares a `mailing list
+<http://groups.google.com/group/quod-libet-development/>`_ and IRC channel
+(#quodlibet on irc.oftc.net) with Quod Libet.
+
+If you need help using Mutagen or would like to discuss the library, please
+use the mailing list or the `issue tracker
+<https://github.com/quodlibet/mutagen/issues>`_.
diff --git a/docs/ext.py b/docs/ext.py
index 397bc1d..8949d62 100644
--- a/docs/ext.py
+++ b/docs/ext.py
@@ -15,10 +15,14 @@ def bug_role(name, rawtext, text, lineno, inliner, *args, **kwargs):
def pr_role(name, rawtext, text, lineno, inliner, *args, **kwargs):
app = inliner.document.settings.env.app
- url_tmpl = app.config.pr_url_template or "missing/%s"
+ if name == "pr":
+ url_tmpl = app.config.pr_url_template
+ else:
+ url_tmpl = app.config.bbpr_url_template
+ url_tmpl = url_tmpl or "missing/%s"
node = nodes.reference(
rawtext,
- "[pr-%s]" % text,
+ "[%s-%s]" % (name, text),
refuri=url_tmpl % text)
return [node], []
@@ -26,5 +30,7 @@ def pr_role(name, rawtext, text, lineno, inliner, *args, **kwargs):
def setup(app):
app.add_role('bug', bug_role)
app.add_config_value('bug_url_template', None, 'env')
+ app.add_role('bb-pr', pr_role)
app.add_role('pr', pr_role)
app.add_config_value('pr_url_template', None, 'env')
+ app.add_config_value('bbpr_url_template', None, 'env')
diff --git a/docs/index.rst b/docs/index.rst
index 6a5a628..a14538d 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -2,31 +2,18 @@
:align: center
:width: 400px
-----
-
.. toctree::
+ :hidden:
:titlesonly:
:maxdepth: 2
- tutorial
changelog
- api_notes
- bugs
+ tutorial
api/index
man/index
-
-=====================
-Mutagen Documentation
-=====================
-
-.. note::
-
- This documentation is still incomplete and it's recommended to read the
- `source <https://bitbucket.org/lazka/mutagen/src/default/mutagen>`__
- for the full details.
-
-What is Mutagen?
-----------------
+ api_notes
+ bugs
+ contact
Mutagen is a Python module to handle audio metadata. It supports ASF, FLAC,
M4A, Monkey's Audio, MP3, Musepack, Ogg Opus, Ogg FLAC, Ogg Speex, Ogg
@@ -43,14 +30,30 @@ dependencies outside the Python standard library.
There is a :doc:`brief tutorial with several API examples.
<tutorial>`
+
+Installing
+----------
+
+::
+
+ pip install mutagen
+
+or
+
+::
+
+ sudo apt-get install python-mutagen python3-mutagen
+
+
Where do I get it?
------------------
-Mutagen is hosted on `Bitbucket <http://bitbucket.org/lazka/mutagen>`_. The
+Mutagen is hosted on `GitHub <https://github.com/quodlibet/mutagen>`_. The
`download page <https://bitbucket.org/lazka/mutagen/downloads>`_ will have the
-latest version or check out the Mercurial repository::
+latest version or check out the git repository::
+
+ $ git clone https://github.com/quodlibet/mutagen.git
- $ hg clone https://bitbucket.org/lazka/mutagen
Why Mutagen?
------------
@@ -71,6 +74,7 @@ Therefore we felt it was necessary to write our own.
test that prevents them from recurring, and new features are committed with
a full test suite.
+
Real World Use
--------------
@@ -80,23 +84,8 @@ collection.
The following software projects are using Mutagen for tagging:
-* `Ex Falso and Quod Libet <http://code.google.com/p/quodlibet/>`_, a flexible tagger and player
+* `Ex Falso and Quod Libet <https://quodlibet.readthedocs.org>`_, a flexible tagger and player
* `Beets <http://beets.radbox.org/>`_, a music library manager and MusicBrainz tagger
-* `Picard <http://musicbrainz.org/doc/PicardQt>`_, cross-platform MusicBrainz tagger
-* `Puddletag <http://puddletag.sourceforge.net/>`_, an audio tag editor
-* `Listen <http://listengnome.free.fr/>`_, a music player for GNOME
+* `Picard <https://picard.musicbrainz.org/>`_, cross-platform MusicBrainz tagger
+* `Puddletag <http://puddletag.net/>`_, an audio tag editor
* `Exaile <http://www.exaile.org/>`_, a media player aiming to be similar to KDE's AmaroK, but for GTK+
-* `ZOMG <http://zomg.alioth.debian.org/>`_, a command-line player for ZSH
-* `pytagsfs <http://www.pytagsfs.org/>`_, virtual file system for organizing media files by metadata
-* Debian's version of `JACK <http://jack.sourceforge.net/>`_, an audio CD ripper, uses Mutagen to tag FLACs
-* Amarok's replaygain `script <http://www.kde-apps.org/content/show.php?content=26073>`_
-
-Contact
--------
-
-For historical and practical reasons, Mutagen shares a `mailing list
-<http://groups.google.com/group/quod-libet-development/>`_ and IRC channel
-(#quodlibet on irc.oftc.net) with Quod Libet. If you need help using Mutagen
-or would like to discuss the library, please use the mailing list. Bugs and
-patches should go to the `issue tracker
-<https://bitbucket.org/lazka/mutagen/issues>`_.
diff --git a/docs/man/index.rst b/docs/man/index.rst
index f6b011b..604fb8f 100644
--- a/docs/man/index.rst
+++ b/docs/man/index.rst
@@ -1,7 +1,8 @@
-Tools
-=====
+Command Line Tools
+==================
.. toctree::
+ :hidden:
:titlesonly:
mid3cp
@@ -11,3 +12,25 @@ Tools
mutagen-inspect
mutagen-pony
+
+In addition to the Python library mutagen installs some command line tools:
+
+:doc:`mid3cp`
+ copies the ID3 tags from a source file to a destination file
+
+:doc:`mid3iconv`
+ converts ID3 tags from legacy encodings to Unicode and stores them using
+ the ID3v2 format
+
+:doc:`mid3v2`
+ is a Mutagen-based replacement for id3lib’s id3v2
+
+:doc:`moggsplit`
+ splits a multiplexed Ogg stream into separate files
+
+:doc:`mutagen-inspect`
+ loads and prints information about an audio file and its tags
+
+:doc:`mutagen-pony`
+ scans any directories given and reports on the kinds of tags in the MP3s
+ it finds in them
diff --git a/docs/tutorial.rst b/docs/tutorial.rst
index 33e5323..ca40095 100644
--- a/docs/tutorial.rst
+++ b/docs/tutorial.rst
@@ -69,7 +69,7 @@ the title of an ID3 tag, you need to do the following::
If you use the ID3 module, you should familiarize yourself with how
ID3v2 tags are stored, by reading the the details of the ID3v2
-standard at http://www.id3.org/develop.html.
+standard at http://id3.org/id3v2.4.0-structure.
ID3 Versions
diff --git a/mutagen/__init__.py b/mutagen/__init__.py
index 03ad7ae..c1abc0b 100644
--- a/mutagen/__init__.py
+++ b/mutagen/__init__.py
@@ -22,9 +22,9 @@ for certain keys, again depending on format.
from mutagen._util import MutagenError
from mutagen._file import FileType, StreamInfo, File
-from mutagen._tags import Metadata, PaddingInfo
+from mutagen._tags import Tags, Metadata, PaddingInfo
-version = (1, 31)
+version = (1, 32)
"""Version tuple."""
version_string = ".".join(map(str, version))
@@ -38,6 +38,8 @@ StreamInfo
File
+Tags
+
Metadata
PaddingInfo
diff --git a/mutagen/_file.py b/mutagen/_file.py
index 5daa252..95f400c 100644
--- a/mutagen/_file.py
+++ b/mutagen/_file.py
@@ -16,8 +16,8 @@ class FileType(DictMixin):
Attributes:
- * info -- stream information (length, bitrate, sample rate)
- * tags -- metadata tags, if any
+ * info -- :class:`StreamInfo` -- (length, bitrate, sample rate)
+ * tags -- :class:`Tags` -- metadata tags, if any
Each file format has different potential tags and stream
information.
@@ -229,9 +229,11 @@ def File(filename, options=None, easy=False):
from mutagen.optimfrog import OptimFROG
from mutagen.aiff import AIFF
from mutagen.aac import AAC
+ from mutagen.smf import SMF
options = [MP3, TrueAudio, OggTheora, OggSpeex, OggVorbis, OggFLAC,
FLAC, AIFF, APEv2File, MP4, ID3FileType, WavPack,
- Musepack, MonkeysAudio, OptimFROG, ASF, OggOpus, AAC]
+ Musepack, MonkeysAudio, OptimFROG, ASF, OggOpus, AAC,
+ SMF]
if not options:
return None
diff --git a/mutagen/_tags.py b/mutagen/_tags.py
index ce250ad..e6365f0 100644
--- a/mutagen/_tags.py
+++ b/mutagen/_tags.py
@@ -71,10 +71,28 @@ class PaddingInfo(object):
type(self).__name__, self.size, self.padding)
-class Metadata(object):
- """An abstract dict-like object.
+class Tags(object):
+ """`Tags` is the base class for many of the tag objects in Mutagen.
- Metadata is the base class for many of the tag objects in Mutagen.
+ In many cases it has a dict like interface.
+ """
+
+ __module__ = "mutagen"
+
+ def pprint(self):
+ """
+ :returns: tag information
+ :rtype: mutagen.text
+ """
+
+ raise NotImplementedError
+
+
+class Metadata(Tags):
+ """Like :class:`Tags` but for standalone tagging formats that are not
+ solely managed by a container format.
+
+ Provides methods to load, save and delete tags.
"""
__module__ = "mutagen"
@@ -83,11 +101,14 @@ class Metadata(object):
if args or kwargs:
self.load(*args, **kwargs)
- def load(self, *args, **kwargs):
+ def load(self, filename, **kwargs):
raise NotImplementedError
def save(self, filename=None):
- """Save changes to a file."""
+ """Save changes to a file.
+
+ :raises mutagen.MutagenError: if saving wasn't possible
+ """
raise NotImplementedError
@@ -96,6 +117,8 @@ class Metadata(object):
In most cases this means any traces of the tag will be removed
from the file.
+
+ :raises mutagen.MutagenError: if deleting wasn't possible
"""
raise NotImplementedError
diff --git a/mutagen/_vorbis.py b/mutagen/_vorbis.py
index da20240..17634e0 100644
--- a/mutagen/_vorbis.py
+++ b/mutagen/_vorbis.py
@@ -57,7 +57,7 @@ class VorbisEncodingError(error):
pass
-class VComment(mutagen.Metadata, list):
+class VComment(mutagen.Tags, list):
"""A Vorbis comment parser, accessor, and renderer.
All comment ordering is preserved. A VComment is a list of
diff --git a/mutagen/asf/__init__.py b/mutagen/asf/__init__.py
index e667192..7d37a86 100644
--- a/mutagen/asf/__init__.py
+++ b/mutagen/asf/__init__.py
@@ -10,7 +10,7 @@
__all__ = ["ASF", "Open"]
-from mutagen import FileType, Metadata, StreamInfo
+from mutagen import FileType, Tags, StreamInfo
from mutagen._util import resize_bytes, DictMixin
from mutagen._compat import string_types, long_, PY3, izip
@@ -79,7 +79,7 @@ class ASFInfo(StreamInfo):
return s
-class ASFTags(list, DictMixin, Metadata):
+class ASFTags(list, DictMixin, Tags):
"""Dictionary containing ASF attributes."""
def __getitem__(self, key):
diff --git a/mutagen/asf/_objects.py b/mutagen/asf/_objects.py
index ed94267..001c58a 100644
--- a/mutagen/asf/_objects.py
+++ b/mutagen/asf/_objects.py
@@ -85,11 +85,34 @@ class HeaderObject(BaseObject):
header = cls()
- size, num_objects = cls.parse_size(fileobj)
+ remaining_header, num_objects = cls.parse_size(fileobj)
+ remaining_header -= 30
+
for i in xrange(num_objects):
- guid, size = struct.unpack("<16sQ", fileobj.read(24))
+ obj_header_size = 24
+ if remaining_header < obj_header_size:
+ raise ASFHeaderError("invalid header size")
+ data = fileobj.read(obj_header_size)
+ if len(data) != obj_header_size:
+ raise ASFHeaderError("truncated")
+ remaining_header -= obj_header_size
+
+ guid, size = struct.unpack("<16sQ", data)
obj = BaseObject._get_object(guid)
- data = fileobj.read(size - 24)
+
+ payload_size = size - obj_header_size
+ if remaining_header < payload_size:
+ raise ASFHeaderError("invalid object size")
+ remaining_header -= payload_size
+
+ try:
+ data = fileobj.read(payload_size)
+ except OverflowError:
+ # read doesn't take 64bit values
+ raise ASFHeaderError("invalid header size")
+ if len(data) != payload_size:
+ raise ASFHeaderError("truncated")
+
obj.parse(asf, data)
header.objects.append(obj)
diff --git a/mutagen/easymp4.py b/mutagen/easymp4.py
index b965f37..8ad7fd0 100644
--- a/mutagen/easymp4.py
+++ b/mutagen/easymp4.py
@@ -6,7 +6,7 @@
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
-from mutagen import Metadata
+from mutagen import Tags
from mutagen._util import DictMixin, dict_match
from mutagen.mp4 import MP4, MP4Tags, error, delete
from ._compat import PY2, text_type, PY3
@@ -19,7 +19,7 @@ class EasyMP4KeyError(error, KeyError, ValueError):
pass
-class EasyMP4Tags(DictMixin, Metadata):
+class EasyMP4Tags(DictMixin, Tags):
"""A file with MPEG-4 iTunes metadata.
Like Vorbis comments, EasyMP4Tags keys are case-insensitive ASCII
diff --git a/mutagen/flac.py b/mutagen/flac.py
index e6cd1cf..f3cc5ab 100644
--- a/mutagen/flac.py
+++ b/mutagen/flac.py
@@ -654,7 +654,7 @@ class FLAC(mutagen.FileType):
* pictures -- list of embedded pictures
"""
- _mimes = ["audio/x-flac", "application/x-flac"]
+ _mimes = ["audio/flac", "audio/x-flac", "application/x-flac"]
info = None
"""A `StreamInfo`"""
@@ -689,9 +689,9 @@ class FLAC(mutagen.FileType):
# so we have to too. Instead of parsing the size
# given, parse an actual Vorbis comment, leaving
# fileobj in the right position.
- # http://code.google.com/p/mutagen/issues/detail?id=52
+ # https://github.com/quodlibet/mutagen/issues/52
# ..same for the Picture block:
- # http://code.google.com/p/mutagen/issues/detail?id=106
+ # https://github.com/quodlibet/mutagen/issues/106
start = fileobj.tell()
block = block_type(fileobj)
real_size = fileobj.tell() - start
diff --git a/mutagen/id3/__init__.py b/mutagen/id3/__init__.py
index 9aef865..11bf54e 100644
--- a/mutagen/id3/__init__.py
+++ b/mutagen/id3/__init__.py
@@ -141,7 +141,7 @@ class ID3Header(object):
# a frame, and if it's *not* a frame we're going to be
# completely lost anyway, this seems to be the most
# correct check.
- # http://code.google.com/p/quodlibet/issues/detail?id=126
+ # https://github.com/quodlibet/quodlibet/issues/126
self._flags ^= 0x40
extsize = 0
fileobj.seek(-4, 1)
@@ -354,6 +354,11 @@ class ID3(DictProxy, mutagen.Metadata):
"""Add a frame to the tag."""
return self.loaded_frame(frame)
+ def __setitem__(self, key, tag):
+ if not isinstance(tag, Frame):
+ raise TypeError("%r not a Frame instance" % tag)
+ super(ID3, self).__setitem__(key, tag)
+
def __read_frames(self, data, frames):
assert self.version >= ID3Header._V22
@@ -635,11 +640,6 @@ class ID3(DictProxy, mutagen.Metadata):
# Get rid of "(xx)Foobr" format.
self["TCON"].genres = self["TCON"].genres
- # ID3v2.2 LNK frames are just way too different to upgrade.
- for frame in self.getall("LINK"):
- if len(frame.frameid) != 4:
- del self[frame.HashKey]
-
mimes = {"PNG": "image/png", "JPG": "image/jpeg"}
for pic in self.getall("APIC"):
if pic.mime in mimes:
diff --git a/mutagen/id3/_frames.py b/mutagen/id3/_frames.py
index c185cef..33ecf5c 100644
--- a/mutagen/id3/_frames.py
+++ b/mutagen/id3/_frames.py
@@ -15,7 +15,8 @@ from ._specs import (
EncodingSpec, ASPIIndexSpec, SizedIntegerSpec, IntegerSpec,
VolumeAdjustmentsSpec, VolumePeakSpec, VolumeAdjustmentSpec,
ChannelSpec, MultiSpec, SynchronizedTextSpec, KeyEventSpec, TimeStampSpec,
- EncodedNumericPartTextSpec, EncodedNumericTextSpec, SpecError)
+ EncodedNumericPartTextSpec, EncodedNumericTextSpec, SpecError,
+ PictureTypeSpec)
from .._compat import text_type, string_types, swap_to_string, iteritems, izip
@@ -62,14 +63,16 @@ class Frame(object):
other._to_other(self)
else:
for checker, val in izip(self._framespec, args):
- setattr(self, checker.name, checker.validate(self, val))
+ setattr(self, checker.name, val)
for checker in self._framespec[len(args):]:
- try:
- validated = checker.validate(
- self, kwargs.get(checker.name, None))
- except ValueError as e:
- raise ValueError("%s: %s" % (checker.name, e))
- setattr(self, checker.name, validated)
+ setattr(self, checker.name, kwargs.get(checker.name))
+
+ def __setattr__(self, name, value):
+ for checker in self._framespec:
+ if checker.name == name:
+ self.__dict__[name] = checker.validate(self, value)
+ return
+ super(Frame, self).__setattr__(name, value)
def _to_other(self, other):
# this impl covers subclasses with the same framespec
@@ -170,8 +173,8 @@ class Frame(object):
except ValueError:
# Some things write synch-unsafe data with either the frame
# or global unsynch flag set. Try to load them as is.
- # https://bitbucket.org/lazka/mutagen/issue/210
- # https://bitbucket.org/lazka/mutagen/issue/223
+ # https://github.com/quodlibet/mutagen/issues/210
+ # https://github.com/quodlibet/mutagen/issues/223
pass
if tflags & Frame.FLAG24_ENCRYPT:
raise ID3EncryptionUnsupportedError
@@ -221,11 +224,17 @@ class FrameOpt(Frame):
super(FrameOpt, self).__init__(*args, **kwargs)
for spec in self._optionalspec:
if spec.name in kwargs:
- validated = spec.validate(self, kwargs[spec.name])
- setattr(self, spec.name, validated)
+ setattr(self, spec.name, kwargs[spec.name])
else:
break
+ def __setattr__(self, name, value):
+ for checker in self._optionalspec:
+ if checker.name == name:
+ self.__dict__[name] = checker.validate(self, value)
+ return
+ super(FrameOpt, self).__setattr__(name, value)
+
def _to_other(self, other):
super(FrameOpt, self)._to_other(other)
@@ -1104,7 +1113,7 @@ class APIC(Frame):
_framespec = [
EncodingSpec('encoding'),
Latin1TextSpec('mime'),
- ByteSpec('type'),
+ PictureTypeSpec('type'),
EncodedTextSpec('desc'),
BinaryDataSpec('data'),
]
@@ -1834,7 +1843,7 @@ class PIC(APIC):
_framespec = [
EncodingSpec('encoding'),
StringSpec('mime', 3),
- ByteSpec('type'),
+ PictureTypeSpec('type'),
EncodedTextSpec('desc'),
BinaryDataSpec('data')
]
@@ -1894,7 +1903,13 @@ class LNK(LINK):
if not isinstance(other, LINK):
raise TypeError
- other.frameid = self.frameid
+ if isinstance(other, LNK):
+ other.frameid = self.frameid
+ else:
+ try:
+ other.frameid = Frames_2_2[self.frameid].__bases__[0].__name__
+ except KeyError:
+ other.frameid = self.frameid.ljust(4)
other.url = self.url
if hasattr(self, "data"):
other.data = self.data
diff --git a/mutagen/id3/_specs.py b/mutagen/id3/_specs.py
index 4358a65..22e4335 100644
--- a/mutagen/id3/_specs.py
+++ b/mutagen/id3/_specs.py
@@ -131,6 +131,19 @@ class ByteSpec(Spec):
return value
+class PictureTypeSpec(ByteSpec):
+
+ def read(self, frame, data):
+ value, data = ByteSpec.read(self, frame, data)
+ return PictureType(value), data
+
+ def validate(self, frame, value):
+ value = ByteSpec.validate(self, frame, value)
+ if value is not None:
+ return PictureType(value)
+ return value
+
+
class IntegerSpec(Spec):
def read(self, frame, data):
return int(BitPaddedInt(data, bits=8)), b''
@@ -180,7 +193,7 @@ class EncodingSpec(ByteSpec):
if enc not in (Encoding.LATIN1, Encoding.UTF16, Encoding.UTF16BE,
Encoding.UTF8):
raise SpecError('Invalid Encoding: %r' % enc)
- return enc, data
+ return Encoding(enc), data
def validate(self, frame, value):
if value is None:
@@ -188,7 +201,7 @@ class EncodingSpec(ByteSpec):
if value not in (Encoding.LATIN1, Encoding.UTF16, Encoding.UTF16BE,
Encoding.UTF8):
raise ValueError('Invalid Encoding: %r' % value)
- return value
+ return Encoding(value)
def _validate23(self, frame, value, **kwargs):
# only 0, 1 are valid in v2.3, default to utf-16
diff --git a/mutagen/m4a.py b/mutagen/m4a.py
index 5730ace..3ed148c 100644
--- a/mutagen/m4a.py
+++ b/mutagen/m4a.py
@@ -13,7 +13,7 @@ since 1.31: mutagen.m4a will no longer work; any operation that could fail
import warnings
-from mutagen import FileType, Metadata, StreamInfo
+from mutagen import FileType, Tags, StreamInfo
from ._util import DictProxy, MutagenError
warnings.warn(
@@ -53,7 +53,7 @@ class M4ACover(bytes):
return self
-class M4ATags(DictProxy, Metadata):
+class M4ATags(DictProxy, Tags):
def load(self, atoms, fileobj):
raise error("deprecated")
diff --git a/mutagen/mp4/__init__.py b/mutagen/mp4/__init__.py
index bc242ee..e3c16a7 100644
--- a/mutagen/mp4/__init__.py
+++ b/mutagen/mp4/__init__.py
@@ -26,7 +26,7 @@ were all consulted.
import struct
import sys
-from mutagen import FileType, Metadata, StreamInfo, PaddingInfo
+from mutagen import FileType, Tags, StreamInfo, PaddingInfo
from mutagen._constants import GENRES
from mutagen._util import (cdata, insert_bytes, DictProxy, MutagenError,
hashable, enum, get_size, resize_bytes)
@@ -237,7 +237,22 @@ def _find_padding(atom_path):
pass
-class MP4Tags(DictProxy, Metadata):
+def _item_sort_key(key, value):
+ # iTunes always writes the tags in order of "relevance", try
+ # to copy it as closely as possible.
+ order = ["\xa9nam", "\xa9ART", "\xa9wrt", "\xa9alb",
+ "\xa9gen", "gnre", "trkn", "disk",
+ "\xa9day", "cpil", "pgap", "pcst", "tmpo",
+ "\xa9too", "----", "covr", "\xa9lyr"]
+ order = dict(izip(order, xrange(len(order))))
+ last = len(order)
+ # If there's no key-based way to distinguish, order by length.
+ # If there's still no way, go by string comparison on the
+ # values, so we at least have something determinstic.
+ return (order.get(key[:4], last), len(repr(value)), repr(value))
+
+
+class MP4Tags(DictProxy, Tags):
r"""Dictionary containing Apple iTunes metadata list key/values.
Keys are four byte identifiers, except for freeform ('----')
@@ -305,7 +320,9 @@ class MP4Tags(DictProxy, Metadata):
def __init__(self, *args, **kwargs):
self._failed_atoms = {}
- super(MP4Tags, self).__init__(*args, **kwargs)
+ super(MP4Tags, self).__init__()
+ if args or kwargs:
+ self.load(*args, **kwargs)
def load(self, atoms, fileobj):
try:
@@ -337,42 +354,30 @@ class MP4Tags(DictProxy, Metadata):
def __setitem__(self, key, value):
if not isinstance(key, str):
raise TypeError("key has to be str")
+ self._render(key, value)
super(MP4Tags, self).__setitem__(key, value)
@classmethod
def _can_load(cls, atoms):
return b"moov.udta.meta.ilst" in atoms
- @staticmethod
- def _key_sort(item):
- (key, v) = item
- # iTunes always writes the tags in order of "relevance", try
- # to copy it as closely as possible.
- order = ["\xa9nam", "\xa9ART", "\xa9wrt", "\xa9alb",
- "\xa9gen", "gnre", "trkn", "disk",
- "\xa9day", "cpil", "pgap", "pcst", "tmpo",
... 857 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/mutagen.git
More information about the Python-modules-commits
mailing list