Merge pull request #1779 from diego-plan9/prompthook

mbsubmit: cleanup and completion
This commit is contained in:
Diego Moreda 2016-01-02 14:11:58 +01:00
commit 7ff999002a
5 changed files with 150 additions and 13 deletions

View file

@ -16,8 +16,10 @@
"""Aid in submitting information to MusicBrainz.
This plugin allows the user to print track information in a format that is
parseable by the MusicBrainz track parser. Programmatic submitting is not
parseable by the MusicBrainz track parser [1]. Programmatic submitting is not
implemented by MusicBrainz yet.
[1] http://wiki.musicbrainz.org/History:How_To_Parse_Track_Listings
"""
from __future__ import (division, absolute_import, print_function,
@ -25,7 +27,6 @@ from __future__ import (division, absolute_import, print_function,
from beets.autotag import Recommendation
from beets.importer import action
from beets.plugins import BeetsPlugin
from beets.ui.commands import PromptChoice
from beetsplug.info import print_data
@ -35,21 +36,26 @@ class MBSubmitPlugin(BeetsPlugin):
def __init__(self):
super(MBSubmitPlugin, self).__init__()
self.config.add({
'format': '$track. $title - $artist ($length)',
'threshold': 'medium',
})
# Validate and store threshold.
self.threshold = self.config['threshold'].as_choice({
'none': Recommendation.none,
'low': Recommendation.low,
'medium': Recommendation.medium,
'strong': Recommendation.strong
})
self.register_listener('before_choose_candidate',
self.before_choose_candidate_event)
def before_choose_candidate_event(self, session, task):
if not task.candidates or task.rec == Recommendation.none:
return [PromptChoice('p', 'Print tracks', self.print_tracks),
PromptChoice('k', 'print tracks and sKip',
self.print_tracks_and_skip)]
if task.rec <= self.threshold:
return [PromptChoice('p', 'Print tracks', self.print_tracks)]
# Callbacks for choices.
def print_tracks(self, session, task):
for i in task.items:
print_data(None, i, '$track. $artist - $title ($length)')
def print_tracks_and_skip(self, session, task):
for i in task.items:
print_data(None, i, '$track. $artist - $title ($length)')
return action.SKIP
print_data(None, i, self.config['format'].get())

View file

@ -11,6 +11,9 @@ New:
:bug:`1778`
* A new :doc:`/plugins/acousticbrainz` fetches acoustic-analysis information
from the `AcousticBrainz`_ project. Thanks to :user:`opatel99`. :bug:`1784`
* A new :doc:`/plugins/mbsubmit` lets you print the tracks of an album in a
format parseable by MusicBrainz track parser during an interactive import
session. :bug:`1779`
.. _AcousticBrainz: http://acousticbrainz.org/

View file

@ -60,6 +60,7 @@ Each plugin has its own set of options that can be defined in a section bearing
lastimport
lyrics
mbcollection
mbsubmit
mbsync
metasync
missing
@ -164,6 +165,7 @@ Miscellaneous
* :doc:`ihate`: Automatically skip albums and tracks during the import process.
* :doc:`info`: Print music files' tags to the console.
* :doc:`mbcollection`: Maintain your MusicBrainz collection list.
* :doc:`mbsubmit`: Print an album's tracks in a MusicBrainz-friendly format.
* :doc:`missing`: List missing tracks.
* :doc:`random`: Randomly choose albums and tracks from your library.
* :doc:`filefilter`: Automatically skip files during the import process based

54
docs/plugins/mbsubmit.rst Normal file
View file

@ -0,0 +1,54 @@
MusicBrainz Submit Plugin
=========================
The ``mbsubmit`` plugin provides an extra prompt choice during an import
session that prints the tracks of the current album in a format that is
parseable by MusicBrainz's `track parser`_.
.. _track parser: http://wiki.musicbrainz.org/History:How_To_Parse_Track_Listings
Usage
-----
Enable the ``mbsubmit`` plugin in your configuration (see :ref:`using-plugins`)
and select the ``Print tracks`` choice which is by default displayed when no
strong recommendations are found for the album::
No matching release found for 3 tracks.
For help, see: http://beets.readthedocs.org/en/latest/faq.html#nomatch
[U]se as-is, as Tracks, Group albums, Skip, Enter search, enter Id, aBort,
Print tracks? p
01. An Obscure Track - An Obscure Artist (3:37)
02. Another Obscure Track - An Obscure Artist (2:05)
03. The Third Track - Another Obscure Artist (3:02)
No matching release found for 3 tracks.
For help, see: http://beets.readthedocs.org/en/latest/faq.html#nomatch
[U]se as-is, as Tracks, Group albums, Skip, Enter search, enter Id, aBort,
Print tracks?
As MusicBrainz currently does not support submitting albums programmatically,
the recommended workflow is to copy the output of the ``Print tracks`` choice
and paste it into the parser that can be found by clicking on the
"Track Parser" button on MusicBrainz "Tracklist" tab.
Configuration
-------------
To configure the plugin, make a ``mbsubmit:`` section in your configuration
file. The following options are available:
- **format**: The format used for printing the tracks, defined using the
same template syntax as beets :doc:`path formats </reference/pathformat>`.
Default: ``$track. $title - $artist ($length)``.
- **threshold**: The minimum strength of the autotagger recommendation that
will cause the ``Print tracks`` choice to be displayed on the prompt.
Default: ``medium`` (causing the choice to be displayed for all albums that
have a recommendation of medium strength or lower). Valid values: ``none``,
``low``, ``medium``, ``strong``.
Please note that some values of the ``threshold`` configuration option might
require other ``beets`` command line switches to be enabled in order to work as
intended. In particular, setting a threshold of ``strong`` will only display
the prompt if ``timid`` mode is enabled. You can find more information about
how the recommendation system works at :ref:`match-config`.

72
test/test_mbsubmit.py Normal file
View file

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
# This file is part of beets.
# Copyright 2016, Adrian Sampson and Diego Moreda.
#
# 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.
from __future__ import (division, absolute_import, print_function,
unicode_literals)
from test._common 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
class MBSubmitPluginTest(TerminalImportSessionSetup, unittest.TestCase,
ImportHelper, TestHelper):
def setUp(self):
self.setup_beets()
self.load_plugins('mbsubmit')
self._create_import_dir(2)
self._setup_import_session()
self.matcher = AutotagStub().install()
def tearDown(self):
self.unload_plugins()
self.teardown_beets()
def test_print_tracks_output(self):
"""Test the output of the "print tracks" choice."""
self.matcher.matching = AutotagStub.BAD
with capture_stdout() as output:
with control_stdin('\n'.join(['p', 's'])):
# Print tracks; Skip
self.importer.run()
# Manually build the string for comparing the output.
tracklist = ('Print tracks? '
'01. Tag Title 1 - Tag Artist (0:01)\n'
'02. Tag Title 2 - Tag Artist (0:01)')
self.assertIn(tracklist, output.getvalue())
def test_print_tracks_output_as_tracks(self):
"""Test the output of the "print tracks" choice, as singletons."""
self.matcher.matching = AutotagStub.BAD
with capture_stdout() as output:
with control_stdin('\n'.join(['t', 's', 'p', 's'])):
# as Tracks; Skip; Print tracks; Skip
self.importer.run()
# Manually build the string for comparing the output.
tracklist = ('Print tracks? '
'02. Tag Title 2 - Tag Artist (0:01)')
self.assertIn(tracklist, output.getvalue())
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)
if __name__ == b'__main__':
unittest.main(defaultTest='suite')