mirror of
https://github.com/clinton-hall/nzbToMedia.git
synced 2025-08-20 13:23:18 -07:00
Update vendored beets to 1.6.0
Updates colorama to 0.4.6 Adds confuse version 1.7.0 Updates jellyfish to 0.9.0 Adds mediafile 0.10.1 Updates munkres to 1.1.4 Updates musicbrainzngs to 0.7.1 Updates mutagen to 1.46.0 Updates pyyaml to 6.0 Updates unidecode to 1.3.6
This commit is contained in:
parent
5073ec0c6f
commit
56c6773c6b
385 changed files with 25143 additions and 18080 deletions
|
@ -1,4 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# This file is part of beets.
|
||||
# Copyright 2016, Peter Schnebel and Johann Klähn.
|
||||
#
|
||||
|
@ -13,11 +12,8 @@
|
|||
# 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
|
||||
|
||||
import mpd
|
||||
import socket
|
||||
import select
|
||||
import time
|
||||
import os
|
||||
|
||||
|
@ -45,14 +41,21 @@ def is_url(path):
|
|||
return path.split('://', 1)[0] in ['http', 'https']
|
||||
|
||||
|
||||
class MPDClientWrapper(object):
|
||||
class MPDClientWrapper:
|
||||
def __init__(self, log):
|
||||
self._log = log
|
||||
|
||||
self.music_directory = (
|
||||
mpd_config['music_directory'].as_str())
|
||||
self.music_directory = mpd_config['music_directory'].as_str()
|
||||
self.strip_path = mpd_config['strip_path'].as_str()
|
||||
|
||||
self.client = mpd.MPDClient(use_unicode=True)
|
||||
# Ensure strip_path end with '/'
|
||||
if not self.strip_path.endswith('/'):
|
||||
self.strip_path += '/'
|
||||
|
||||
self._log.debug('music_directory: {0}', self.music_directory)
|
||||
self._log.debug('strip_path: {0}', self.strip_path)
|
||||
|
||||
self.client = mpd.MPDClient()
|
||||
|
||||
def connect(self):
|
||||
"""Connect to the MPD.
|
||||
|
@ -63,11 +66,11 @@ class MPDClientWrapper(object):
|
|||
if host[0] in ['/', '~']:
|
||||
host = os.path.expanduser(host)
|
||||
|
||||
self._log.info(u'connecting to {0}:{1}', host, port)
|
||||
self._log.info('connecting to {0}:{1}', host, port)
|
||||
try:
|
||||
self.client.connect(host, port)
|
||||
except socket.error as e:
|
||||
raise ui.UserError(u'could not connect to MPD: {0}'.format(e))
|
||||
except OSError as e:
|
||||
raise ui.UserError(f'could not connect to MPD: {e}')
|
||||
|
||||
password = mpd_config['password'].as_str()
|
||||
if password:
|
||||
|
@ -75,7 +78,7 @@ class MPDClientWrapper(object):
|
|||
self.client.password(password)
|
||||
except mpd.CommandError as e:
|
||||
raise ui.UserError(
|
||||
u'could not authenticate to MPD: {0}'.format(e)
|
||||
f'could not authenticate to MPD: {e}'
|
||||
)
|
||||
|
||||
def disconnect(self):
|
||||
|
@ -90,12 +93,12 @@ class MPDClientWrapper(object):
|
|||
"""
|
||||
try:
|
||||
return getattr(self.client, command)()
|
||||
except (select.error, mpd.ConnectionError) as err:
|
||||
self._log.error(u'{0}', err)
|
||||
except (OSError, mpd.ConnectionError) as err:
|
||||
self._log.error('{0}', err)
|
||||
|
||||
if retries <= 0:
|
||||
# if we exited without breaking, we couldn't reconnect in time :(
|
||||
raise ui.UserError(u'communication with MPD server failed')
|
||||
raise ui.UserError('communication with MPD server failed')
|
||||
|
||||
time.sleep(RETRY_INTERVAL)
|
||||
|
||||
|
@ -107,18 +110,26 @@ class MPDClientWrapper(object):
|
|||
self.connect()
|
||||
return self.get(command, retries=retries - 1)
|
||||
|
||||
def playlist(self):
|
||||
"""Return the currently active playlist. Prefixes paths with the
|
||||
music_directory, to get the absolute path.
|
||||
def currentsong(self):
|
||||
"""Return the path to the currently playing song, along with its
|
||||
songid. Prefixes paths with the music_directory, to get the absolute
|
||||
path.
|
||||
In some cases, we need to remove the local path from MPD server,
|
||||
we replace 'strip_path' with ''.
|
||||
`strip_path` defaults to ''.
|
||||
"""
|
||||
result = {}
|
||||
for entry in self.get('playlistinfo'):
|
||||
result = None
|
||||
entry = self.get('currentsong')
|
||||
if 'file' in entry:
|
||||
if not is_url(entry['file']):
|
||||
result[entry['id']] = os.path.join(
|
||||
self.music_directory, entry['file'])
|
||||
file = entry['file']
|
||||
if file.startswith(self.strip_path):
|
||||
file = file[len(self.strip_path):]
|
||||
result = os.path.join(self.music_directory, file)
|
||||
else:
|
||||
result[entry['id']] = entry['file']
|
||||
return result
|
||||
result = entry['file']
|
||||
self._log.debug('returning: {0}', result)
|
||||
return result, entry.get('id')
|
||||
|
||||
def status(self):
|
||||
"""Return the current status of the MPD.
|
||||
|
@ -132,7 +143,7 @@ class MPDClientWrapper(object):
|
|||
return self.get('idle')
|
||||
|
||||
|
||||
class MPDStats(object):
|
||||
class MPDStats:
|
||||
def __init__(self, lib, log):
|
||||
self.lib = lib
|
||||
self._log = log
|
||||
|
@ -164,7 +175,7 @@ class MPDStats(object):
|
|||
if item:
|
||||
return item
|
||||
else:
|
||||
self._log.info(u'item not found: {0}', displayable_path(path))
|
||||
self._log.info('item not found: {0}', displayable_path(path))
|
||||
|
||||
def update_item(self, item, attribute, value=None, increment=None):
|
||||
"""Update the beets item. Set attribute to value or increment the value
|
||||
|
@ -182,7 +193,7 @@ class MPDStats(object):
|
|||
item[attribute] = value
|
||||
item.store()
|
||||
|
||||
self._log.debug(u'updated: {0} = {1} [{2}]',
|
||||
self._log.debug('updated: {0} = {1} [{2}]',
|
||||
attribute,
|
||||
item[attribute],
|
||||
displayable_path(item.path))
|
||||
|
@ -229,29 +240,31 @@ class MPDStats(object):
|
|||
"""Updates the play count of a song.
|
||||
"""
|
||||
self.update_item(song['beets_item'], 'play_count', increment=1)
|
||||
self._log.info(u'played {0}', displayable_path(song['path']))
|
||||
self._log.info('played {0}', displayable_path(song['path']))
|
||||
|
||||
def handle_skipped(self, song):
|
||||
"""Updates the skip count of a song.
|
||||
"""
|
||||
self.update_item(song['beets_item'], 'skip_count', increment=1)
|
||||
self._log.info(u'skipped {0}', displayable_path(song['path']))
|
||||
self._log.info('skipped {0}', displayable_path(song['path']))
|
||||
|
||||
def on_stop(self, status):
|
||||
self._log.info(u'stop')
|
||||
self._log.info('stop')
|
||||
|
||||
if self.now_playing:
|
||||
# if the current song stays the same it means that we stopped on the
|
||||
# current track and should not record a skip.
|
||||
if self.now_playing and self.now_playing['id'] != status.get('songid'):
|
||||
self.handle_song_change(self.now_playing)
|
||||
|
||||
self.now_playing = None
|
||||
|
||||
def on_pause(self, status):
|
||||
self._log.info(u'pause')
|
||||
self._log.info('pause')
|
||||
self.now_playing = None
|
||||
|
||||
def on_play(self, status):
|
||||
playlist = self.mpd.playlist()
|
||||
path = playlist.get(status['songid'])
|
||||
|
||||
path, songid = self.mpd.currentsong()
|
||||
|
||||
if not path:
|
||||
return
|
||||
|
@ -276,16 +289,17 @@ class MPDStats(object):
|
|||
self.handle_song_change(self.now_playing)
|
||||
|
||||
if is_url(path):
|
||||
self._log.info(u'playing stream {0}', displayable_path(path))
|
||||
self._log.info('playing stream {0}', displayable_path(path))
|
||||
self.now_playing = None
|
||||
return
|
||||
|
||||
self._log.info(u'playing {0}', displayable_path(path))
|
||||
self._log.info('playing {0}', displayable_path(path))
|
||||
|
||||
self.now_playing = {
|
||||
'started': time.time(),
|
||||
'remaining': remaining,
|
||||
'path': path,
|
||||
'started': time.time(),
|
||||
'remaining': remaining,
|
||||
'path': path,
|
||||
'id': songid,
|
||||
'beets_item': self.get_item(path),
|
||||
}
|
||||
|
||||
|
@ -305,7 +319,7 @@ class MPDStats(object):
|
|||
if handler:
|
||||
handler(status)
|
||||
else:
|
||||
self._log.debug(u'unhandled status "{0}"', status)
|
||||
self._log.debug('unhandled status "{0}"', status)
|
||||
|
||||
events = self.mpd.events()
|
||||
|
||||
|
@ -313,37 +327,38 @@ class MPDStats(object):
|
|||
class MPDStatsPlugin(plugins.BeetsPlugin):
|
||||
|
||||
item_types = {
|
||||
'play_count': types.INTEGER,
|
||||
'skip_count': types.INTEGER,
|
||||
'play_count': types.INTEGER,
|
||||
'skip_count': types.INTEGER,
|
||||
'last_played': library.DateType(),
|
||||
'rating': types.FLOAT,
|
||||
'rating': types.FLOAT,
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
super(MPDStatsPlugin, self).__init__()
|
||||
super().__init__()
|
||||
mpd_config.add({
|
||||
'music_directory': config['directory'].as_filename(),
|
||||
'rating': True,
|
||||
'rating_mix': 0.75,
|
||||
'host': os.environ.get('MPD_HOST', u'localhost'),
|
||||
'port': 6600,
|
||||
'password': u'',
|
||||
'strip_path': '',
|
||||
'rating': True,
|
||||
'rating_mix': 0.75,
|
||||
'host': os.environ.get('MPD_HOST', 'localhost'),
|
||||
'port': int(os.environ.get('MPD_PORT', 6600)),
|
||||
'password': '',
|
||||
})
|
||||
mpd_config['password'].redact = True
|
||||
|
||||
def commands(self):
|
||||
cmd = ui.Subcommand(
|
||||
'mpdstats',
|
||||
help=u'run a MPD client to gather play statistics')
|
||||
help='run a MPD client to gather play statistics')
|
||||
cmd.parser.add_option(
|
||||
u'--host', dest='host', type='string',
|
||||
help=u'set the hostname of the server to connect to')
|
||||
'--host', dest='host', type='string',
|
||||
help='set the hostname of the server to connect to')
|
||||
cmd.parser.add_option(
|
||||
u'--port', dest='port', type='int',
|
||||
help=u'set the port of the MPD server to connect to')
|
||||
'--port', dest='port', type='int',
|
||||
help='set the port of the MPD server to connect to')
|
||||
cmd.parser.add_option(
|
||||
u'--password', dest='password', type='string',
|
||||
help=u'set the password of the MPD server to connect to')
|
||||
'--password', dest='password', type='string',
|
||||
help='set the password of the MPD server to connect to')
|
||||
|
||||
def func(lib, opts, args):
|
||||
mpd_config.set_args(opts)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue