fix #685: truncate files larger than 50MB for upload

The new behavior is as follows:

1. If the file size is greater than 50MB, and the 'truncate' config
option is 'no', skip the file.

2. If the file size is greater than 50MB, and the 'truncate' config
option is 'yes', reencode the file to ogg, and truncate to first 5
minutes.
This commit is contained in:
Pedro Silva 2014-04-14 09:55:28 +02:00
parent a45ac4a9d6
commit cf2f78ef55
3 changed files with 55 additions and 4 deletions

View file

@ -36,6 +36,7 @@ RETRY_INTERVAL = 10
DEVNULL = open(os.devnull, 'wb')
ALLOWED_FORMATS = ('MP3', 'OGG', 'AAC')
UPLOAD_MAX_SIZE = 50 * 1024 * 1024
# The attributes we can import and where to store them in beets fields.
ATTRIBUTES = {
@ -111,6 +112,7 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin):
'codegen': None,
'upload': True,
'convert': True,
'truncate': True,
})
self.config.add(ATTRIBUTES)
@ -310,6 +312,36 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin):
)
return dest
def truncate(self, item):
"""Truncates an item to a size less than UPLOAD_MAX_SIZE."""
fd, dest = tempfile.mkstemp(u'.ogg')
os.close(fd)
source = item.path
log.info(u'echonest: truncating {0} to {1}'.format(
util.displayable_path(source),
util.displayable_path(dest),
))
command = u'ffmpeg -t 300 -i $source -y -acodec copy $dest'
opts = []
for arg in command.split():
arg = arg.encode('utf-8')
opts.append(Template(arg).substitute(source=source, dest=dest))
# Run the command.
try:
util.command_output(opts)
except (OSError, subprocess.CalledProcessError) as exc:
log.debug(u'echonest: truncate failed: {0}'.format(exc))
util.remove(dest)
return
log.info(u'echonest: truncate encoding {0}'.format(
util.displayable_path(source))
)
return dest
def analyze(self, item):
"""Upload the item to the EchoNest for analysis. May require to
convert the item to a supported media format.
@ -326,6 +358,15 @@ class EchonestMetadataPlugin(plugins.BeetsPlugin):
else:
return
if os.stat(item.path).st_size > UPLOAD_MAX_SIZE:
if config['echonest']['truncate']:
source = self.convert(item)
if not source:
log.debug(u'echonest: failed to truncate file')
return
else:
return
# Upload the audio file.
log.info(u'echonest: uploading file, please be patient')
track = self._echofun(pyechonest.track.track_from_filename,

View file

@ -16,7 +16,7 @@ New stuff:
* :doc:`/plugins/lyrics`: Lyrics should now be found for more songs. Searching
is now sensitive to featured artists and parenthesized title suffixes.
When a song has multiple titles, lyrics from all the named songs are now
concatenated. Thanks to Fabrice Laporte and Paul Phillips.
concatenated. Thanks to Fabrice Laporte and Paul Phillips.
* Add support for `initial_key` as field in the library and tag for
media files. When the user sets this field with ``beet modify
initial_key=Am`` the media files will reflect this in their tags. The
@ -28,6 +28,8 @@ New stuff:
Fixes:
* :doc:`/plugins/echonest`: Truncate files larger than 50MB before uploading for
analysis.
* :doc:`/plugins/fetchart`: Fix a crash when the server does not specify a
content type. Thanks to Lee Reinhardt.
* :doc:`/plugins/convert`: The ``--keep-new`` flag now works correctly

View file

@ -71,13 +71,21 @@ can not be identified by other means. If you don't want that, disable the
echonest:
upload: no
The Echo Nest server only supports a limited range of file formats. The
``plugin`` automatically converts unsupported files to ``ogg``. If you don't
want that, disable the ``convert`` config option like so::
The Echo Nest server only supports a limited range of file formats. The plugin
automatically converts unsupported files to ``ogg``. If you don't want that,
disable the ``convert`` config option like so::
echonest:
convert: no
The Echo Nest server does not allow uploading of files with sizes greater than
50MB. The plugin automatically truncates large files to their first 5
minutes. If you don't want that, disable the ``truncate`` config option like
so::
echonest:
truncate: no
To enable fingerprinting, you'll need to tell the plugin where to find the
Echoprint or ENMFP codegen binary. Use the ``codegen`` key under the
``echonest`` section like so::