mirror of
https://github.com/beetbox/beets.git
synced 2026-01-27 02:23:36 +01:00
Merge branch 'master' of https://github.com/beetbox/beets
This commit is contained in:
commit
fcc6c6bc80
68 changed files with 282 additions and 220 deletions
|
|
@ -56,15 +56,13 @@ import imghdr
|
|||
import os
|
||||
import traceback
|
||||
import enum
|
||||
|
||||
from beets import logging
|
||||
from beets.util import displayable_path, syspath, as_string
|
||||
import logging
|
||||
import six
|
||||
|
||||
|
||||
__all__ = ['UnreadableFileError', 'FileTypeError', 'MediaFile']
|
||||
|
||||
log = logging.getLogger('beets')
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Human-readable type names.
|
||||
TYPES = {
|
||||
|
|
@ -90,7 +88,7 @@ class UnreadableFileError(Exception):
|
|||
"""Mutagen is not able to extract information from the file.
|
||||
"""
|
||||
def __init__(self, path):
|
||||
Exception.__init__(self, displayable_path(path))
|
||||
Exception.__init__(self, repr(path))
|
||||
|
||||
|
||||
class FileTypeError(UnreadableFileError):
|
||||
|
|
@ -100,11 +98,10 @@ class FileTypeError(UnreadableFileError):
|
|||
mutagen type is not supported by `Mediafile`.
|
||||
"""
|
||||
def __init__(self, path, mutagen_type=None):
|
||||
path = displayable_path(path)
|
||||
if mutagen_type is None:
|
||||
msg = path
|
||||
msg = repr(path)
|
||||
else:
|
||||
msg = u'{0}: of mutagen type {1}'.format(path, mutagen_type)
|
||||
msg = u'{0}: of mutagen type {1}'.format(repr(path), mutagen_type)
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
|
||||
|
|
@ -112,7 +109,7 @@ class MutagenError(UnreadableFileError):
|
|||
"""Raised when Mutagen fails unexpectedly---probably due to a bug.
|
||||
"""
|
||||
def __init__(self, path, mutagen_exc):
|
||||
msg = u'{0}: {1}'.format(displayable_path(path), mutagen_exc)
|
||||
msg = u'{0}: {1}'.format(repr(path), mutagen_exc)
|
||||
Exception.__init__(self, msg)
|
||||
|
||||
|
||||
|
|
@ -134,12 +131,12 @@ def mutagen_call(action, path, func, *args, **kwargs):
|
|||
try:
|
||||
return func(*args, **kwargs)
|
||||
except mutagen.MutagenError as exc:
|
||||
log.debug(u'{} failed: {}', action, six.text_type(exc))
|
||||
log.debug(u'%s failed: %s', action, six.text_type(exc))
|
||||
raise UnreadableFileError(path)
|
||||
except Exception as exc:
|
||||
# Isolate bugs in Mutagen.
|
||||
log.debug(u'{}', traceback.format_exc())
|
||||
log.error(u'uncaught Mutagen exception in {}: {}', action, exc)
|
||||
log.debug(u'%s', traceback.format_exc())
|
||||
log.error(u'uncaught Mutagen exception in %s: %s', action, exc)
|
||||
raise MutagenError(path, exc)
|
||||
|
||||
|
||||
|
|
@ -405,7 +402,7 @@ class Image(object):
|
|||
try:
|
||||
type = list(ImageType)[type]
|
||||
except IndexError:
|
||||
log.debug(u"ignoring unknown image type index {0}", type)
|
||||
log.debug(u"ignoring unknown image type index %s", type)
|
||||
type = ImageType.other
|
||||
self.type = type
|
||||
|
||||
|
|
@ -1412,7 +1409,6 @@ class MediaFile(object):
|
|||
By default, MP3 files are saved with ID3v2.4 tags. You can use
|
||||
the older ID3v2.3 standard by specifying the `id3v23` option.
|
||||
"""
|
||||
path = syspath(path)
|
||||
self.path = path
|
||||
|
||||
self.mgfile = mutagen_call('open', path, mutagen.File, path)
|
||||
|
|
@ -1488,7 +1484,12 @@ class MediaFile(object):
|
|||
"""
|
||||
for property, descriptor in cls.__dict__.items():
|
||||
if isinstance(descriptor, MediaField):
|
||||
yield as_string(property)
|
||||
if isinstance(property, bytes):
|
||||
# On Python 2, class field names are bytes. This method
|
||||
# produces text strings.
|
||||
yield property.decode('utf8', 'ignore')
|
||||
else:
|
||||
yield property
|
||||
|
||||
@classmethod
|
||||
def _field_sort_name(cls, name):
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class BadFiles(BeetsPlugin):
|
|||
ui.print_(u"{}: checker exited withs status {}"
|
||||
.format(ui.colorize('text_error', dpath), status))
|
||||
for line in output:
|
||||
ui.print_(" {}".format(displayable_path(line)))
|
||||
ui.print_(u" {}".format(displayable_path(line)))
|
||||
elif errors > 0:
|
||||
ui.print_(u"{}: checker found {} errors or warnings"
|
||||
.format(ui.colorize('text_warning', dpath), errors))
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ Changelog
|
|||
1.4.2 (in development)
|
||||
----------------------
|
||||
|
||||
Changelog goes here!
|
||||
Fixes:
|
||||
|
||||
* :doc:`/plugins/badfiles`: Fix a crash on non-ASCII filenames. :bug:`2299`
|
||||
|
||||
|
||||
1.4.1 (November 25, 2016)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ file. The available options are:
|
|||
Default: None.
|
||||
- **google_engine**: The custom search engine to use.
|
||||
Default: The `beets custom search engine`_, which searches the entire web.
|
||||
**fanarttv_key**: The personal API key for requesting art from
|
||||
- **fanarttv_key**: The personal API key for requesting art from
|
||||
fanart.tv. See below.
|
||||
- **store_source**: If enabled, fetchart stores the artwork's source in a
|
||||
flexible tag named ``art_source``. See below for the rationale behind this.
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ The Web backend is built using a simple REST+JSON API with the excellent
|
|||
`Backbone.js`_. This allows future non-Web clients to use the same backend API.
|
||||
|
||||
.. _Flask: http://flask.pocoo.org/
|
||||
.. _Backbone.js: http://documentcloud.github.com/backbone/
|
||||
.. _Backbone.js: http://backbonejs.org
|
||||
|
||||
Eventually, to make the Web player really viable, we should use a Flash fallback
|
||||
for unsupported formats/browsers. There are a number of options for this:
|
||||
|
|
|
|||
|
|
@ -333,6 +333,29 @@ class Bag(object):
|
|||
return self.fields.get(key)
|
||||
|
||||
|
||||
# Convenience methods for setting up a temporary sandbox directory for tests
|
||||
# that need to interact with the filesystem.
|
||||
|
||||
class TempDirMixin(object):
|
||||
"""Text mixin for creating and deleting a temporary directory.
|
||||
"""
|
||||
|
||||
def create_temp_dir(self):
|
||||
"""Create a temporary directory and assign it into `self.temp_dir`.
|
||||
Call `remove_temp_dir` later to delete it.
|
||||
"""
|
||||
path = tempfile.mkdtemp()
|
||||
if not isinstance(path, bytes):
|
||||
path = path.encode('utf8')
|
||||
self.temp_dir = path
|
||||
|
||||
def remove_temp_dir(self):
|
||||
"""Delete the temporary directory created by `create_temp_dir`.
|
||||
"""
|
||||
if os.path.isdir(self.temp_dir):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
|
||||
# Platform mocking.
|
||||
|
||||
@contextmanager
|
||||
|
|
|
|||
|
|
@ -16,12 +16,13 @@
|
|||
"""Tests for the 'acousticbrainz' plugin.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import json
|
||||
import os.path
|
||||
import unittest
|
||||
|
||||
from test._common import unittest, RSRC
|
||||
from test._common import RSRC
|
||||
|
||||
from beetsplug.acousticbrainz import AcousticPlugin, ABSCHEME
|
||||
|
||||
|
|
|
|||
|
|
@ -19,12 +19,12 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
import responses
|
||||
from mock import patch
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beetsplug import fetchart
|
||||
from beets.autotag import AlbumInfo, AlbumMatch
|
||||
from beets import config
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import re
|
||||
import copy
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets import autotag
|
||||
from beets.autotag import match
|
||||
from beets.autotag.hooks import Distance, string_dist
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from beetsplug import bucket
|
||||
from beets import config, ui
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ import yaml
|
|||
from mock import patch
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import unittest
|
||||
|
||||
from beets import ui
|
||||
from beets import config
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
from beets.library import Library
|
||||
import six
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import re
|
||||
import os.path
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test import helper
|
||||
from test.helper import control_stdin, capture_log
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from datetime import datetime
|
||||
import unittest
|
||||
import time
|
||||
from beets.dbcore.query import _parse_periods, DateInterval, DateQuery
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ from __future__ import division, absolute_import, print_function
|
|||
import os
|
||||
import shutil
|
||||
import sqlite3
|
||||
import unittest
|
||||
from six import assertRaisesRegex
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets import dbcore
|
||||
from tempfile import mkstemp
|
||||
import six
|
||||
|
|
|
|||
|
|
@ -17,8 +17,9 @@
|
|||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from test import _common
|
||||
from test._common import unittest, Bag
|
||||
from test._common import Bag
|
||||
|
||||
from beetsplug.discogs import DiscogsPlugin
|
||||
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
import codecs
|
||||
import unittest
|
||||
|
||||
from mock import patch
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper, control_stdin
|
||||
from test.test_ui_importer import TerminalImportSessionSetup
|
||||
from test.test_importer import ImportHelper, AutotagStub
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ import os.path
|
|||
import shutil
|
||||
from mock import patch, MagicMock
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.mediafile import MediaFile
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
from beetsplug import embyupdate
|
||||
import unittest
|
||||
import responses
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import TestHelper
|
||||
from beets import util
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import capture_log
|
||||
from test.test_importer import ImportHelper
|
||||
from beets import config
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import shutil
|
|||
import os
|
||||
import stat
|
||||
from os.path import join
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test._common import item, touch
|
||||
import beets.library
|
||||
from beets import util
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import TestHelper
|
||||
from beetsplug import ftintitle
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
import sys
|
||||
import tempfile
|
||||
from beets.util import hidden
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os.path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets import config
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from beets import importer
|
||||
from beets.library import Item
|
||||
from beetsplug.ihate import IHatePlugin
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ from __future__ import division, absolute_import, print_function
|
|||
"""Tests for the `importadded` plugin."""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
from test._common import unittest
|
||||
from test.test_importer import ImportHelper, AutotagStub
|
||||
from beets import importer
|
||||
from beets import util
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ from tempfile import mkstemp
|
|||
from zipfile import ZipFile
|
||||
from tarfile import TarFile
|
||||
from mock import patch, Mock
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets.util import displayable_path, bytestring_path, py3_path
|
||||
from test.helper import TestImportSession, TestHelper, has_program, capture_log
|
||||
from beets import importer
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import os
|
|||
import os.path
|
||||
import tempfile
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
from test._common import unittest
|
||||
from beets import config
|
||||
from beets.library import Item, Album, Library
|
||||
from beetsplug.importfeeds import ImportFeedsPlugin
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.mediafile import MediaFile
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ from beets import library
|
|||
from beets.util import bytestring_path, _fsencoding
|
||||
from beetsplug.ipfs import IPFSPlugin
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
import unittest
|
||||
import os
|
||||
|
||||
from test import _common
|
||||
from test.helper import TestHelper
|
||||
|
||||
|
||||
@patch('beets.util.command_output', Mock())
|
||||
class IPFSPluginTest(unittest.TestCase, TestHelper):
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from mock import patch
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.library import Item
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from mock import Mock
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beetsplug import lastgenre
|
||||
from beets import config
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ import re
|
|||
import unicodedata
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test._common import item
|
||||
import beets.library
|
||||
import beets.mediafile
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ import sys
|
|||
import threading
|
||||
import logging as log
|
||||
from six import StringIO
|
||||
import unittest
|
||||
|
||||
import beets.logging as blog
|
||||
from beets import plugins, ui
|
||||
import beetsplug
|
||||
from test import _common
|
||||
from test._common import unittest, TestCase
|
||||
from test._common import TestCase
|
||||
from test import helper
|
||||
import six
|
||||
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
from test import _common
|
||||
import sys
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from mock import MagicMock
|
||||
|
||||
from test._common import unittest
|
||||
from beetsplug import lyrics
|
||||
from beets.library import Item
|
||||
from beets.util import confit, bytestring_path
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets.autotag import mb
|
||||
from beets import config
|
||||
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import capture_stdout, control_stdin, TestHelper
|
||||
from test.test_importer import ImportHelper, AutotagStub
|
||||
from test.test_ui_importer import TerminalImportSessionSetup
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from mock import patch
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper,\
|
||||
generate_album_info, \
|
||||
generate_track_info, \
|
||||
|
|
|
|||
|
|
@ -20,20 +20,14 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import datetime
|
||||
import time
|
||||
import unittest
|
||||
from six import assertCountEqual
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets.mediafile import MediaFile, MediaField, Image, \
|
||||
MP3DescStorageStyle, StorageStyle, MP4StorageStyle, \
|
||||
ASFStorageStyle, ImageType, CoverArtField, UnreadableFileError
|
||||
from beets.library import Item
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.util import bytestring_path
|
||||
import six
|
||||
from beets.mediafile import MediaFile, Image, \
|
||||
ImageType, CoverArtField, UnreadableFileError
|
||||
|
||||
|
||||
class ArtTestMixin(object):
|
||||
|
|
@ -298,80 +292,8 @@ class GenreListTestMixin(object):
|
|||
assertCountEqual(self, mediafile.genres, [u'the genre', u'another'])
|
||||
|
||||
|
||||
field_extension = MediaField(
|
||||
MP3DescStorageStyle(u'customtag'),
|
||||
MP4StorageStyle('----:com.apple.iTunes:customtag'),
|
||||
StorageStyle('customtag'),
|
||||
ASFStorageStyle('customtag'),
|
||||
)
|
||||
|
||||
|
||||
class ExtendedFieldTestMixin(object):
|
||||
|
||||
def test_extended_field_write(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mediafile = self._mediafile_fixture('empty')
|
||||
mediafile.customtag = u'F#'
|
||||
mediafile.save()
|
||||
|
||||
mediafile = MediaFile(mediafile.path)
|
||||
self.assertEqual(mediafile.customtag, u'F#')
|
||||
|
||||
finally:
|
||||
delattr(MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_write_extended_tag_from_item(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mediafile = self._mediafile_fixture('empty')
|
||||
self.assertIsNone(mediafile.customtag)
|
||||
|
||||
item = Item(path=mediafile.path, customtag=u'Gb')
|
||||
item.write()
|
||||
mediafile = MediaFile(mediafile.path)
|
||||
self.assertEqual(mediafile.customtag, u'Gb')
|
||||
|
||||
finally:
|
||||
delattr(MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_read_flexible_attribute_from_file(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mediafile = self._mediafile_fixture('empty')
|
||||
mediafile.update({'customtag': u'F#'})
|
||||
mediafile.save()
|
||||
|
||||
item = Item.from_path(mediafile.path)
|
||||
self.assertEqual(item['customtag'], u'F#')
|
||||
|
||||
finally:
|
||||
delattr(MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_invalid_descriptor(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
MediaFile.add_field('somekey', True)
|
||||
self.assertIn(u'must be an instance of MediaField',
|
||||
six.text_type(cm.exception))
|
||||
|
||||
def test_overwrite_property(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
MediaFile.add_field('artist', MediaField())
|
||||
self.assertIn(u'property "artist" already exists',
|
||||
six.text_type(cm.exception))
|
||||
|
||||
|
||||
class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin,
|
||||
ExtendedFieldTestMixin):
|
||||
_common.TempDirMixin):
|
||||
"""Test writing and reading tags. Subclasses must set ``extension`` and
|
||||
``audio_properties``.
|
||||
"""
|
||||
|
|
@ -456,11 +378,10 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin,
|
|||
]
|
||||
|
||||
def setUp(self):
|
||||
self.temp_dir = bytestring_path(tempfile.mkdtemp())
|
||||
self.create_temp_dir()
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.isdir(self.temp_dir):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
self.remove_temp_dir()
|
||||
|
||||
def test_read_nonexisting(self):
|
||||
mediafile = self._mediafile_fixture('full')
|
||||
|
|
@ -709,7 +630,9 @@ class ReadWriteTestBase(ArtTestMixin, GenreListTestMixin,
|
|||
self.fail('\n '.join(errors))
|
||||
|
||||
def _mediafile_fixture(self, name):
|
||||
name = bytestring_path(name + '.' + self.extension)
|
||||
name = name + '.' + self.extension
|
||||
if not isinstance(name, bytes):
|
||||
name = name.encode('utf8')
|
||||
src = os.path.join(_common.RSRC, name)
|
||||
target = os.path.join(self.temp_dir, name)
|
||||
shutil.copy(src, target)
|
||||
|
|
|
|||
|
|
@ -19,18 +19,16 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
import mutagen.id3
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.util import bytestring_path
|
||||
import beets.mediafile
|
||||
from beets import mediafile
|
||||
import six
|
||||
|
||||
|
||||
_sc = beets.mediafile._safe_cast
|
||||
_sc = mediafile._safe_cast
|
||||
|
||||
|
||||
class EdgeTest(unittest.TestCase):
|
||||
|
|
@ -38,7 +36,7 @@ class EdgeTest(unittest.TestCase):
|
|||
# Some files have an ID3 frame that has a list with no elements.
|
||||
# This is very hard to produce, so this is just the first 8192
|
||||
# bytes of a file found "in the wild".
|
||||
emptylist = beets.mediafile.MediaFile(
|
||||
emptylist = mediafile.MediaFile(
|
||||
os.path.join(_common.RSRC, b'emptylist.mp3')
|
||||
)
|
||||
genre = emptylist.genre
|
||||
|
|
@ -47,7 +45,7 @@ class EdgeTest(unittest.TestCase):
|
|||
def test_release_time_with_space(self):
|
||||
# Ensures that release times delimited by spaces are ignored.
|
||||
# Amie Street produces such files.
|
||||
space_time = beets.mediafile.MediaFile(
|
||||
space_time = mediafile.MediaFile(
|
||||
os.path.join(_common.RSRC, b'space_time.mp3')
|
||||
)
|
||||
self.assertEqual(space_time.year, 2009)
|
||||
|
|
@ -57,7 +55,7 @@ class EdgeTest(unittest.TestCase):
|
|||
def test_release_time_with_t(self):
|
||||
# Ensures that release times delimited by Ts are ignored.
|
||||
# The iTunes Store produces such files.
|
||||
t_time = beets.mediafile.MediaFile(
|
||||
t_time = mediafile.MediaFile(
|
||||
os.path.join(_common.RSRC, b't_time.m4a')
|
||||
)
|
||||
self.assertEqual(t_time.year, 1987)
|
||||
|
|
@ -67,20 +65,20 @@ class EdgeTest(unittest.TestCase):
|
|||
def test_tempo_with_bpm(self):
|
||||
# Some files have a string like "128 BPM" in the tempo field
|
||||
# rather than just a number.
|
||||
f = beets.mediafile.MediaFile(os.path.join(_common.RSRC, b'bpm.mp3'))
|
||||
f = mediafile.MediaFile(os.path.join(_common.RSRC, b'bpm.mp3'))
|
||||
self.assertEqual(f.bpm, 128)
|
||||
|
||||
def test_discc_alternate_field(self):
|
||||
# Different taggers use different vorbis comments to reflect
|
||||
# the disc and disc count fields: ensure that the alternative
|
||||
# style works.
|
||||
f = beets.mediafile.MediaFile(os.path.join(_common.RSRC, b'discc.ogg'))
|
||||
f = mediafile.MediaFile(os.path.join(_common.RSRC, b'discc.ogg'))
|
||||
self.assertEqual(f.disc, 4)
|
||||
self.assertEqual(f.disctotal, 5)
|
||||
|
||||
def test_old_ape_version_bitrate(self):
|
||||
media_file = os.path.join(_common.RSRC, b'oldape.ape')
|
||||
f = beets.mediafile.MediaFile(media_file)
|
||||
f = mediafile.MediaFile(media_file)
|
||||
self.assertEqual(f.bitrate, 0)
|
||||
|
||||
def test_only_magic_bytes_jpeg(self):
|
||||
|
|
@ -92,13 +90,13 @@ class EdgeTest(unittest.TestCase):
|
|||
with open(magic_bytes_file, 'rb') as f:
|
||||
jpg_data = f.read()
|
||||
self.assertEqual(
|
||||
beets.mediafile._imghdr_what_wrapper(jpg_data), 'jpeg')
|
||||
mediafile._imghdr_what_wrapper(jpg_data), 'jpeg')
|
||||
|
||||
def test_soundcheck_non_ascii(self):
|
||||
# Make sure we don't crash when the iTunes SoundCheck field contains
|
||||
# non-ASCII binary data.
|
||||
f = beets.mediafile.MediaFile(os.path.join(_common.RSRC,
|
||||
b'soundcheck-nonascii.m4a'))
|
||||
f = mediafile.MediaFile(os.path.join(_common.RSRC,
|
||||
b'soundcheck-nonascii.m4a'))
|
||||
self.assertEqual(f.rg_track_gain, 0.0)
|
||||
|
||||
|
||||
|
|
@ -146,7 +144,7 @@ class InvalidValueToleranceTest(unittest.TestCase):
|
|||
self.assertEqual(v, 1.0)
|
||||
|
||||
|
||||
class SafetyTest(unittest.TestCase, TestHelper):
|
||||
class SafetyTest(unittest.TestCase, _common.TempDirMixin):
|
||||
def setUp(self):
|
||||
self.create_temp_dir()
|
||||
|
||||
|
|
@ -158,35 +156,35 @@ class SafetyTest(unittest.TestCase, TestHelper):
|
|||
with open(fn, 'w') as f:
|
||||
f.write(data)
|
||||
try:
|
||||
self.assertRaises(exc, beets.mediafile.MediaFile, fn)
|
||||
self.assertRaises(exc, mediafile.MediaFile, fn)
|
||||
finally:
|
||||
os.unlink(fn) # delete the temporary file
|
||||
|
||||
def test_corrupt_mp3_raises_unreadablefileerror(self):
|
||||
# Make sure we catch Mutagen reading errors appropriately.
|
||||
self._exccheck(b'corrupt.mp3', beets.mediafile.UnreadableFileError)
|
||||
self._exccheck(b'corrupt.mp3', mediafile.UnreadableFileError)
|
||||
|
||||
def test_corrupt_mp4_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'corrupt.m4a', beets.mediafile.UnreadableFileError)
|
||||
self._exccheck(b'corrupt.m4a', mediafile.UnreadableFileError)
|
||||
|
||||
def test_corrupt_flac_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'corrupt.flac', beets.mediafile.UnreadableFileError)
|
||||
self._exccheck(b'corrupt.flac', mediafile.UnreadableFileError)
|
||||
|
||||
def test_corrupt_ogg_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'corrupt.ogg', beets.mediafile.UnreadableFileError)
|
||||
self._exccheck(b'corrupt.ogg', mediafile.UnreadableFileError)
|
||||
|
||||
def test_invalid_ogg_header_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'corrupt.ogg', beets.mediafile.UnreadableFileError,
|
||||
self._exccheck(b'corrupt.ogg', mediafile.UnreadableFileError,
|
||||
'OggS\x01vorbis')
|
||||
|
||||
def test_corrupt_monkeys_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'corrupt.ape', beets.mediafile.UnreadableFileError)
|
||||
self._exccheck(b'corrupt.ape', mediafile.UnreadableFileError)
|
||||
|
||||
def test_invalid_extension_raises_filetypeerror(self):
|
||||
self._exccheck(b'something.unknown', beets.mediafile.FileTypeError)
|
||||
self._exccheck(b'something.unknown', mediafile.FileTypeError)
|
||||
|
||||
def test_magic_xml_raises_unreadablefileerror(self):
|
||||
self._exccheck(b'nothing.xml', beets.mediafile.UnreadableFileError,
|
||||
self._exccheck(b'nothing.xml', mediafile.UnreadableFileError,
|
||||
"ftyp")
|
||||
|
||||
@unittest.skipUnless(_common.HAVE_SYMLINK, u'platform lacks symlink')
|
||||
|
|
@ -194,8 +192,8 @@ class SafetyTest(unittest.TestCase, TestHelper):
|
|||
fn = os.path.join(_common.RSRC, b'brokenlink')
|
||||
os.symlink('does_not_exist', fn)
|
||||
try:
|
||||
self.assertRaises(beets.mediafile.UnreadableFileError,
|
||||
beets.mediafile.MediaFile, fn)
|
||||
self.assertRaises(mediafile.UnreadableFileError,
|
||||
mediafile.MediaFile, fn)
|
||||
finally:
|
||||
os.unlink(fn)
|
||||
|
||||
|
|
@ -206,19 +204,19 @@ class SideEffectsTest(unittest.TestCase):
|
|||
|
||||
def test_opening_tagless_file_leaves_untouched(self):
|
||||
old_mtime = os.stat(self.empty).st_mtime
|
||||
beets.mediafile.MediaFile(self.empty)
|
||||
mediafile.MediaFile(self.empty)
|
||||
new_mtime = os.stat(self.empty).st_mtime
|
||||
self.assertEqual(old_mtime, new_mtime)
|
||||
|
||||
|
||||
class MP4EncodingTest(unittest.TestCase, TestHelper):
|
||||
class MP4EncodingTest(unittest.TestCase, _common.TempDirMixin):
|
||||
def setUp(self):
|
||||
self.create_temp_dir()
|
||||
src = os.path.join(_common.RSRC, b'full.m4a')
|
||||
self.path = os.path.join(self.temp_dir, b'test.m4a')
|
||||
shutil.copy(src, self.path)
|
||||
|
||||
self.mf = beets.mediafile.MediaFile(self.path)
|
||||
self.mf = mediafile.MediaFile(self.path)
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_temp_dir()
|
||||
|
|
@ -226,18 +224,18 @@ class MP4EncodingTest(unittest.TestCase, TestHelper):
|
|||
def test_unicode_label_in_m4a(self):
|
||||
self.mf.label = u'foo\xe8bar'
|
||||
self.mf.save()
|
||||
new_mf = beets.mediafile.MediaFile(self.path)
|
||||
new_mf = mediafile.MediaFile(self.path)
|
||||
self.assertEqual(new_mf.label, u'foo\xe8bar')
|
||||
|
||||
|
||||
class MP3EncodingTest(unittest.TestCase, TestHelper):
|
||||
class MP3EncodingTest(unittest.TestCase, _common.TempDirMixin):
|
||||
def setUp(self):
|
||||
self.create_temp_dir()
|
||||
src = os.path.join(_common.RSRC, b'full.mp3')
|
||||
self.path = os.path.join(self.temp_dir, b'test.mp3')
|
||||
shutil.copy(src, self.path)
|
||||
|
||||
self.mf = beets.mediafile.MediaFile(self.path)
|
||||
self.mf = mediafile.MediaFile(self.path)
|
||||
|
||||
def test_comment_with_latin1_encoding(self):
|
||||
# Set up the test file with a Latin1-encoded COMM frame. The encoding
|
||||
|
|
@ -250,7 +248,7 @@ class MP3EncodingTest(unittest.TestCase, TestHelper):
|
|||
self.mf.save()
|
||||
|
||||
|
||||
class ZeroLengthMediaFile(beets.mediafile.MediaFile):
|
||||
class ZeroLengthMediaFile(mediafile.MediaFile):
|
||||
@property
|
||||
def length(self):
|
||||
return 0.0
|
||||
|
|
@ -271,7 +269,7 @@ class TypeTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
super(TypeTest, self).setUp()
|
||||
path = os.path.join(_common.RSRC, b'full.mp3')
|
||||
self.mf = beets.mediafile.MediaFile(path)
|
||||
self.mf = mediafile.MediaFile(path)
|
||||
|
||||
def test_year_integer_in_string(self):
|
||||
self.mf.year = u'2009'
|
||||
|
|
@ -303,45 +301,45 @@ class TypeTest(unittest.TestCase):
|
|||
|
||||
class SoundCheckTest(unittest.TestCase):
|
||||
def test_round_trip(self):
|
||||
data = beets.mediafile._sc_encode(1.0, 1.0)
|
||||
gain, peak = beets.mediafile._sc_decode(data)
|
||||
data = mediafile._sc_encode(1.0, 1.0)
|
||||
gain, peak = mediafile._sc_decode(data)
|
||||
self.assertEqual(gain, 1.0)
|
||||
self.assertEqual(peak, 1.0)
|
||||
|
||||
def test_decode_zero(self):
|
||||
data = b' 80000000 80000000 00000000 00000000 00000000 00000000 ' \
|
||||
b'00000000 00000000 00000000 00000000'
|
||||
gain, peak = beets.mediafile._sc_decode(data)
|
||||
gain, peak = mediafile._sc_decode(data)
|
||||
self.assertEqual(gain, 0.0)
|
||||
self.assertEqual(peak, 0.0)
|
||||
|
||||
def test_malformatted(self):
|
||||
gain, peak = beets.mediafile._sc_decode(b'foo')
|
||||
gain, peak = mediafile._sc_decode(b'foo')
|
||||
self.assertEqual(gain, 0.0)
|
||||
self.assertEqual(peak, 0.0)
|
||||
|
||||
def test_special_characters(self):
|
||||
gain, peak = beets.mediafile._sc_decode(u'caf\xe9'.encode('utf-8'))
|
||||
gain, peak = mediafile._sc_decode(u'caf\xe9'.encode('utf-8'))
|
||||
self.assertEqual(gain, 0.0)
|
||||
self.assertEqual(peak, 0.0)
|
||||
|
||||
def test_decode_handles_unicode(self):
|
||||
# Most of the time, we expect to decode the raw bytes. But some formats
|
||||
# might give us text strings, which we need to handle.
|
||||
gain, peak = beets.mediafile._sc_decode(u'caf\xe9')
|
||||
gain, peak = mediafile._sc_decode(u'caf\xe9')
|
||||
self.assertEqual(gain, 0.0)
|
||||
self.assertEqual(peak, 0.0)
|
||||
|
||||
|
||||
class ID3v23Test(unittest.TestCase, TestHelper):
|
||||
def _make_test(self, ext='mp3', id3v23=False):
|
||||
class ID3v23Test(unittest.TestCase, _common.TempDirMixin):
|
||||
def _make_test(self, ext=b'mp3', id3v23=False):
|
||||
self.create_temp_dir()
|
||||
src = os.path.join(_common.RSRC,
|
||||
bytestring_path('full.{0}'.format(ext)))
|
||||
b'full.' + ext)
|
||||
self.path = os.path.join(self.temp_dir,
|
||||
bytestring_path('test.{0}'.format(ext)))
|
||||
b'test.' + ext)
|
||||
shutil.copy(src, self.path)
|
||||
return beets.mediafile.MediaFile(self.path, id3v23=id3v23)
|
||||
return mediafile.MediaFile(self.path, id3v23=id3v23)
|
||||
|
||||
def _delete_test(self):
|
||||
self.remove_temp_dir()
|
||||
|
|
@ -369,7 +367,7 @@ class ID3v23Test(unittest.TestCase, TestHelper):
|
|||
self._delete_test()
|
||||
|
||||
def test_v23_on_non_mp3_is_noop(self):
|
||||
mf = self._make_test('m4a', id3v23=True)
|
||||
mf = self._make_test(b'm4a', id3v23=True)
|
||||
try:
|
||||
mf.year = 2013
|
||||
mf.save()
|
||||
|
|
@ -386,9 +384,9 @@ class ID3v23Test(unittest.TestCase, TestHelper):
|
|||
mf = self._make_test(id3v23=v23)
|
||||
try:
|
||||
mf.images = [
|
||||
beets.mediafile.Image(b'data', desc=u""),
|
||||
beets.mediafile.Image(b'data', desc=u"foo"),
|
||||
beets.mediafile.Image(b'data', desc=u"\u0185"),
|
||||
mediafile.Image(b'data', desc=u""),
|
||||
mediafile.Image(b'data', desc=u"foo"),
|
||||
mediafile.Image(b'data', desc=u"\u0185"),
|
||||
]
|
||||
mf.save()
|
||||
apic_frames = mf.mgfile.tags.getall('APIC')
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ import time
|
|||
from datetime import datetime
|
||||
from beets.library import Item
|
||||
from beets.util import py3_path
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from mock import Mock, patch, call, ANY
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.library import Item
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import platform
|
||||
import unittest
|
||||
from mock import patch, Mock
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
from beets.util import displayable_path
|
||||
from beetsplug.permissions import (check_permissions,
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import six
|
||||
import unittest
|
||||
|
||||
from test._common import unittest
|
||||
from beets.util import pipeline
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
|
||||
import unittest
|
||||
from mock import patch, ANY
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper, control_stdin
|
||||
|
||||
from beets.ui import UserError
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from beetsplug import bpd
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
from beetsplug.plexupdate import get_music_section, update_plex
|
||||
import unittest
|
||||
import responses
|
||||
|
||||
|
||||
|
|
|
|||
107
test/test_plugin_mediafield.py
Normal file
107
test/test_plugin_mediafield.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# This file is part of beets.
|
||||
# Copyright 2016, Adrian Sampson.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
"""Tests the facility that lets plugins add custom field to MediaFile.
|
||||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import os
|
||||
import six
|
||||
import shutil
|
||||
|
||||
from test import _common
|
||||
from beets.library import Item
|
||||
from beets import mediafile
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.util import bytestring_path
|
||||
|
||||
|
||||
field_extension = mediafile.MediaField(
|
||||
mediafile.MP3DescStorageStyle(u'customtag'),
|
||||
mediafile.MP4StorageStyle('----:com.apple.iTunes:customtag'),
|
||||
mediafile.StorageStyle('customtag'),
|
||||
mediafile.ASFStorageStyle('customtag'),
|
||||
)
|
||||
|
||||
|
||||
class ExtendedFieldTestMixin(_common.TestCase):
|
||||
|
||||
def _mediafile_fixture(self, name, extension='mp3'):
|
||||
name = bytestring_path(name + '.' + extension)
|
||||
src = os.path.join(_common.RSRC, name)
|
||||
target = os.path.join(self.temp_dir, name)
|
||||
shutil.copy(src, target)
|
||||
return mediafile.MediaFile(target)
|
||||
|
||||
def test_extended_field_write(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mf = self._mediafile_fixture('empty')
|
||||
mf.customtag = u'F#'
|
||||
mf.save()
|
||||
|
||||
mf = mediafile.MediaFile(mf.path)
|
||||
self.assertEqual(mf.customtag, u'F#')
|
||||
|
||||
finally:
|
||||
delattr(mediafile.MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_write_extended_tag_from_item(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mf = self._mediafile_fixture('empty')
|
||||
self.assertIsNone(mf.customtag)
|
||||
|
||||
item = Item(path=mf.path, customtag=u'Gb')
|
||||
item.write()
|
||||
mf = mediafile.MediaFile(mf.path)
|
||||
self.assertEqual(mf.customtag, u'Gb')
|
||||
|
||||
finally:
|
||||
delattr(mediafile.MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_read_flexible_attribute_from_file(self):
|
||||
plugin = BeetsPlugin()
|
||||
plugin.add_media_field('customtag', field_extension)
|
||||
|
||||
try:
|
||||
mf = self._mediafile_fixture('empty')
|
||||
mf.update({'customtag': u'F#'})
|
||||
mf.save()
|
||||
|
||||
item = Item.from_path(mf.path)
|
||||
self.assertEqual(item['customtag'], u'F#')
|
||||
|
||||
finally:
|
||||
delattr(mediafile.MediaFile, 'customtag')
|
||||
Item._media_fields.remove('customtag')
|
||||
|
||||
def test_invalid_descriptor(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
mediafile.MediaFile.add_field('somekey', True)
|
||||
self.assertIn(u'must be an instance of MediaField',
|
||||
six.text_type(cm.exception))
|
||||
|
||||
def test_overwrite_property(self):
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
mediafile.MediaFile.add_field('artist', mediafile.MediaField())
|
||||
self.assertIn(u'property "artist" already exists',
|
||||
six.text_type(cm.exception))
|
||||
|
|
@ -19,6 +19,7 @@ import os
|
|||
from mock import patch, Mock, ANY
|
||||
import shutil
|
||||
import itertools
|
||||
import unittest
|
||||
|
||||
from beets.importer import SingletonImportTask, SentinelImportTask, \
|
||||
ArchiveImportTask, action
|
||||
|
|
@ -30,7 +31,7 @@ from beets.util import displayable_path, bytestring_path
|
|||
|
||||
from test.test_importer import ImportHelper, AutotagStub
|
||||
from test.test_ui_importer import TerminalImportSessionSetup
|
||||
from test._common import unittest, RSRC
|
||||
from test._common import RSRC
|
||||
from test import helper
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@ from functools import partial
|
|||
from mock import patch
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test import helper
|
||||
|
||||
import beets.library
|
||||
|
|
|
|||
|
|
@ -16,14 +16,15 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
import six
|
||||
|
||||
from test.helper import TestHelper, has_program
|
||||
|
||||
from beets import config
|
||||
from beets.mediafile import MediaFile
|
||||
from beetsplug.replaygain import (FatalGstreamerPluginReplayGainError,
|
||||
GStreamerBackend)
|
||||
import six
|
||||
|
||||
try:
|
||||
import gi
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ from __future__ import division, absolute_import, print_function
|
|||
from os import path, remove
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import unittest
|
||||
|
||||
from mock import Mock, MagicMock
|
||||
|
||||
|
|
@ -29,7 +30,6 @@ from beets.util import syspath, bytestring_path, py3_path, CHAR_REPLACE
|
|||
from beets.ui import UserError
|
||||
from beets import config
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@
|
|||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
import beets.library
|
||||
from beets import dbcore
|
||||
from beets import config
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import responses
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets import config
|
||||
from beets.library import Item
|
||||
from beetsplug import spotify
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@
|
|||
"""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
from beets.util import functemplate
|
||||
import unittest
|
||||
import six
|
||||
from beets.util import functemplate
|
||||
|
||||
|
||||
def _normexpr(expr):
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test import _common
|
||||
from beets import config
|
||||
from beetsplug.the import ThePlugin, PATTERN_A, PATTERN_THE, FORMAT
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import os.path
|
|||
from mock import Mock, patch, call
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree
|
||||
import unittest
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.util import bytestring_path
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import time
|
||||
from datetime import datetime
|
||||
import unittest
|
||||
|
||||
from test._common import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.util.confit import ConfigValueError
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import subprocess
|
|||
import platform
|
||||
from copy import deepcopy
|
||||
import six
|
||||
import unittest
|
||||
|
||||
from mock import patch, Mock
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from test.helper import capture_stdout, has_program, TestHelper, control_stdin
|
||||
|
||||
from beets import library
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ from __future__ import division, absolute_import, print_function
|
|||
|
||||
import os
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
|
||||
from beets import library
|
||||
from beets import ui
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ test_importer module. But here the test importer inherits from
|
|||
"""
|
||||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
import unittest
|
||||
|
||||
from test._common import unittest, DummyIO
|
||||
from test._common import DummyIO
|
||||
from test import test_importer
|
||||
from beets.ui.commands import TerminalImportSession
|
||||
from beets import importer
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
|
||||
from beets import ui
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import sys
|
|||
import re
|
||||
import os
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
from mock import patch, Mock
|
||||
|
||||
from test._common import unittest
|
||||
from test import _common
|
||||
from beets import util
|
||||
import six
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@
|
|||
"""Tests for the virtual filesystem builder.."""
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from test import _common
|
||||
from test._common import unittest
|
||||
from beets import library
|
||||
from beets import vfs
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
import unittest
|
||||
from six import assertCountEqual
|
||||
|
||||
from test._common import unittest
|
||||
from test import _common
|
||||
import json
|
||||
from beets.library import Item, Album
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
from __future__ import division, absolute_import, print_function
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
from test.helper import TestHelper
|
||||
|
||||
from beets.library import Item
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ from __future__ import division, absolute_import, print_function
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
from test._common import unittest
|
||||
import unittest
|
||||
|
||||
pkgpath = os.path.dirname(__file__) or '.'
|
||||
sys.path.append(pkgpath)
|
||||
|
|
|
|||
2
tox.ini
2
tox.ini
|
|
@ -4,7 +4,7 @@
|
|||
# and then run "tox" from this directory.
|
||||
|
||||
[tox]
|
||||
envlist = py27-test, py27-flake8, docs
|
||||
envlist = py27-test, py35-test, py27-flake8, docs
|
||||
|
||||
# The exhaustive list of environments is:
|
||||
# envlist = py{27,34,35}-{test,cov}, py{27,34,35}-flake8, docs
|
||||
|
|
|
|||
Loading…
Reference in a new issue