Merge branch 'master' into CaseInsensitiveSearch

This commit is contained in:
Malte Ried 2015-09-11 12:39:04 +02:00
commit 2e052fc93b
6 changed files with 73 additions and 21 deletions

View file

@ -18,7 +18,7 @@ from beets import config
from beets.plugins import BeetsPlugin
def get_music_section(host, port, token):
def get_music_section(host, port, token, library_name):
"""Getting the section key for the music library in Plex.
"""
api_endpoint = append_token('library/sections', token)
@ -30,15 +30,15 @@ def get_music_section(host, port, token):
# Parse xml tree and extract music section key.
tree = ET.fromstring(r.text)
for child in tree.findall('Directory'):
if child.get('title') == 'Music':
if child.get('title') == library_name:
return child.get('key')
def update_plex(host, port, token):
def update_plex(host, port, token, library_name):
"""Sends request to the Plex api to start a library refresh.
"""
# Getting section key and build url.
section_key = get_music_section(host, port, token)
section_key = get_music_section(host, port, token, library_name)
api_endpoint = 'library/sections/{0}/refresh'.format(section_key)
api_endpoint = append_token(api_endpoint, token)
url = urljoin('http://{0}:{1}'.format(host, port), api_endpoint)
@ -64,7 +64,8 @@ class PlexUpdate(BeetsPlugin):
config['plex'].add({
u'host': u'localhost',
u'port': 32400,
u'token': u''})
u'token': u'',
u'library_name': u'Music'})
self.register_listener('database_change', self.listen_for_db_change)
@ -82,7 +83,8 @@ class PlexUpdate(BeetsPlugin):
update_plex(
config['plex']['host'].get(),
config['plex']['port'].get(),
config['plex']['token'].get())
config['plex']['token'].get(),
config['plex']['library_name'].get())
self._log.info('... started.')
except requests.exceptions.RequestException:

View file

@ -700,6 +700,23 @@ class AudioToolsBackend(Backend):
"""
return [self._compute_track_gain(item) for item in items]
def _title_gain(self, rg, audiofile):
"""Get the gain result pair from PyAudioTools using the `ReplayGain`
instance `rg` for the given `audiofile`.
Wraps `rg.title_gain(audiofile.to_pcm())` and throws a
`ReplayGainError` when the library fails.
"""
try:
# The method needs an audiotools.PCMReader instance that can
# be obtained from an audiofile instance.
return rg.title_gain(audiofile.to_pcm())
except ValueError as exc:
# `audiotools.replaygain` can raise a `ValueError` if the sample
# rate is incorrect.
self._log.debug('error in rg.title_gain() call: {}', exc)
raise ReplayGainError('audiotools audio data error')
def _compute_track_gain(self, item):
"""Compute ReplayGain value for the requested item.
@ -707,17 +724,10 @@ class AudioToolsBackend(Backend):
"""
audiofile = self.open_audio_file(item)
rg = self.init_replaygain(audiofile, item)
# Each call to title_gain on a replaygain object return peak and gain
# Each call to title_gain on a ReplayGain object returns peak and gain
# of the track.
# Note that the method needs an audiotools.PCMReader instance that can
# be obtained from an audiofile instance.
try:
rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm())
except ValueError as exc:
# `audiotools.replaygain` can raise a `ValueError` if the sample
# rate is incorrect.
self._log.debug('error in rg.title_gain() call: {}', exc)
raise ReplayGainError('audiotools audio data error')
rg_track_gain, rg_track_peak = rg._title_gain(rg, audiofile)
self._log.debug(u'ReplayGain for track {0} - {1}: {2:.2f}, {3:.2f}',
item.artist, item.title, rg_track_gain, rg_track_peak)
@ -740,7 +750,7 @@ class AudioToolsBackend(Backend):
track_gains = []
for item in album.items():
audiofile = self.open_audio_file(item)
rg_track_gain, rg_track_peak = rg.title_gain(audiofile.to_pcm())
rg_track_gain, rg_track_peak = self._title_gain(rg, audiofile)
track_gains.append(
Gain(gain=rg_track_gain, peak=rg_track_peak)
)

View file

@ -20,6 +20,8 @@ The new features:
:bug:`1591` :bug:`733`
* :doc:`/plugins/play`: You can now configure the number of tracks that
trigger a "lots of music" warning. :bug:`1577`
* :doc:`/plugins/plexupdate`: A new ``library_name`` option allows you to select
which Plex library to update. :bug:`1572` :bug:`1595`
Fixes:

View file

@ -39,3 +39,5 @@ The available options under the ``plex:`` section are:
Default: 32400.
- **token**: The Plex Home token.
Default: Empty.
- **library_name**: The name of the Plex library to update.
Default: ``Music``

View file

@ -82,6 +82,26 @@ class EmbedartCliTest(_common.TestCase, TestHelper):
mediafile = MediaFile(syspath(item.path))
self.assertEqual(mediafile.images[0].data, self.image_data)
def test_embed_art_remove_art_file(self):
self._setup_data()
album = self.add_album_fixture()
logging.getLogger('beets.embedart').setLevel(logging.DEBUG)
handle, tmp_path = tempfile.mkstemp()
os.write(handle, self.image_data)
os.close(handle)
album.artpath = tmp_path
album.store()
config['embedart']['remove_art_file'] = True
self.run_command('embedart')
if os.path.isfile(tmp_path):
os.remove(tmp_path)
self.fail('Artwork file {0} was not deleted'.format(tmp_path))
def test_art_file_missing(self):
self.add_album_fixture()
logging.getLogger('beets.embedart').setLevel(logging.DEBUG)

View file

@ -8,9 +8,12 @@ import responses
class PlexUpdateTest(unittest.TestCase, TestHelper):
def add_response_get_music_section(self):
def add_response_get_music_section(self, section_name='Music'):
"""Create response for mocking the get_music_section function.
"""
escaped_section_name = section_name.replace('"', '\\"')
body = (
'<?xml version="1.0" encoding="UTF-8"?>'
'<MediaContainer size="3" allowSync="0" '
@ -28,7 +31,7 @@ class PlexUpdateTest(unittest.TestCase, TestHelper):
'</Directory>'
'<Directory allowSync="0" art="/:/resources/artist-fanart.jpg" '
'filters="1" refreshing="0" thumb="/:/resources/artist.png" '
'key="2" type="artist" title="Music" '
'key="2" type="artist" title="' + escaped_section_name + '" '
'composite="/library/sections/2/composite/1416929243" '
'agent="com.plexapp.agents.lastfm" scanner="Plex Music Scanner" '
'language="en" uuid="90897c95-b3bd-4778-a9c8-1f43cb78f047" '
@ -88,7 +91,19 @@ class PlexUpdateTest(unittest.TestCase, TestHelper):
self.assertEqual(get_music_section(
self.config['plex']['host'],
self.config['plex']['port'],
self.config['plex']['token']), '2')
self.config['plex']['token'],
self.config['plex']['library_name'].get()), '2')
@responses.activate
def test_get_named_music_section(self):
# Adding response.
self.add_response_get_music_section('My Music Library')
self.assertEqual(get_music_section(
self.config['plex']['host'],
self.config['plex']['port'],
self.config['plex']['token'],
'My Music Library'), '2')
@responses.activate
def test_update_plex(self):
@ -100,7 +115,8 @@ class PlexUpdateTest(unittest.TestCase, TestHelper):
self.assertEqual(update_plex(
self.config['plex']['host'],
self.config['plex']['port'],
self.config['plex']['token']).status_code, 200)
self.config['plex']['token'],
self.config['plex']['library_name'].get()).status_code, 200)
def suite():