diff --git a/beetsplug/chroma.py b/beetsplug/chroma.py index 2e2ce52b5..e8df67497 100644 --- a/beetsplug/chroma.py +++ b/beetsplug/chroma.py @@ -157,7 +157,14 @@ class AcoustidPlugin(plugins.BeetsPlugin): raise ui.UserError('no Acoustid user API key provided') submit_items(apikey, lib.items(ui.decargs(args))) submit_cmd.func = submit_cmd_func - return [submit_cmd] + + fingerprint_cmd = ui.Subcommand('fingerprint', + help='fingerprints files with no fingerprint stored') + def fingerprint_cmd_func(lib, opts, args): + for item in lib.items(ui.decargs(args)): + fingerprint_item(item, lib=lib, write=True) + fingerprint_cmd.func = fingerprint_cmd_func + return [submit_cmd, fingerprint_cmd] # Hooks into import process. @@ -195,28 +202,7 @@ def submit_items(userkey, items, chunksize=64): del data[:] for item in items: - # Get a fingerprint and length for this track. - if not item.length: - log.info(u'{0}: no duration available'.format( - util.displayable_path(item.path) - )) - continue - elif item.acoustid_fingerprint: - log.info(u'{0}: using existing fingerprint'.format( - util.displayable_path(item.path) - )) - fp = item.acoustid_fingerprint - else: - log.info(u'{0}: fingerprinting'.format( - util.displayable_path(item.path) - )) - try: - _, fp = acoustid.fingerprint_file(item.path) - except acoustid.FingerprintGenerationError as exc: - log.info( - 'fingerprint generation failed: {0}'.format(exc) - ) - continue + fp = fingerprint_item(item) # Construct a submission dictionary for this item. item_data = { @@ -246,3 +232,43 @@ def submit_items(userkey, items, chunksize=64): # Submit remaining data in a final chunk. if data: submit_chunk() + + +def fingerprint_item(item, lib=None, write=False): + """Fingerprints files that don't already have prints stored + """ + # Get a fingerprint and length for this track. + if not item.length: + log.info(u'{0}: no duration available'.format( + util.displayable_path(item.path) + )) + return + elif item.acoustid_fingerprint: + if not write: + log.info(u'{0}: using existing fingerprint'.format( + util.displayable_path(item.path) + )) + return item.acoustid_fingerprint + log.info(u'{0}: skipping. fingerprint exists'.format( + util.displayable_path(item.path) + )) + else: + log.info(u'{0}: fingerprinting'.format( + util.displayable_path(item.path) + )) + try: + _, fp = acoustid.fingerprint_file(item.path) + item.acoustid_fingerprint = fp + if write and lib is not None: + log.info(u'{0}: writing fingerprint'.format( + util.displayable_path(item.path) + )) + item.write() + lib.store(item) + return item.acoustid_fingerprint + except acoustid.FingerprintGenerationError as exc: + log.info( + 'fingerprint generation failed: {0}'.format(exc) + ) + return + diff --git a/docs/plugins/chroma.rst b/docs/plugins/chroma.rst index b24a4816a..0677ca957 100644 --- a/docs/plugins/chroma.rst +++ b/docs/plugins/chroma.rst @@ -45,7 +45,7 @@ Next, you will need a mechanism for decoding audio files supported by the * On Linux, you can install `GStreamer for Python`_, `FFmpeg`_, or `MAD`_ and `pymad`_. How you install these will depend on your distribution. For example, on Ubuntu, run ``apt-get install python-gst0.10-dev``. On Arch Linux, you want - ``pacman -S gstreamer0.10-python``. + ``pacman -S gstreamer0.10-python``. * On Windows, try the Gstreamer "WinBuilds" from the `OSSBuild`_ project. @@ -78,6 +78,10 @@ editing your :doc:`configuration file `. Put ``chroma`` on your ``plugins:`` line. With that, beets will use fingerprinting the next time you run ``beet import``. +You can also use ``beet fingerprint`` to fingerprint the tracks already imported +without fingerprints. (You can provide a query to fingerprint a subset of your +library). + .. _submitfp: Submitting Fingerprints