LFM = {'apikey': 'NG4xcDlxcXJwMjk4MTZycTgwM3E3b3I5MTEzb240cG8',
'host':'ws.audioscrobbler.com',
- 'version': '2.0',
- }
+ 'version': '2.0',}
ECH = {'apikey': 'WlRKQkhTS0JHWFVDUEZZRFA',
'host': 'developer.echonest.com',
- 'version': 'v4',
- }
+ 'version': 'v4',}
WAIT_BETWEEN_REQUESTS = timedelta(days=0, seconds=2)
SOCKET_TIMEOUT = 6
"""
# TODO: ain't working for "sticker find" and "sticker list"
tracks_listing = ["playlistfind", "playlistid", "playlistinfo",
- "playlistsearch", "plchanges", "listplaylistinfo", "find",
- "search", "sticker find",]
+ "playlistsearch", "plchanges", "listplaylistinfo", "find",
+ "search", "sticker find",]
track_obj = ['currentsong']
if self._comm in tracks_listing + track_obj:
# pylint: disable=w0142
def __skipped_track(self, old_curr):
if (self.state == 'stop'
- or not hasattr(old_curr, 'id')
- or not hasattr(self.current, 'id')):
+ or not hasattr(old_curr, 'id')
+ or not hasattr(self.current, 'id')):
return False
return self.current.id != old_curr.id # pylint: disable=no-member
self.log.info('Player: Flushing cache!')
else:
self.log.info('Player: Initialising cache!')
- self._cache = {
- 'artists': frozenset(),
- 'nombid_artists': frozenset(),
- }
+ self._cache = {'artists': frozenset(),
+ 'nombid_artists': frozenset(),}
self._cache['artists'] = frozenset(self._execute('list', ['artist']))
if Artist.use_mbid:
self._cache['nombid_artists'] = frozenset(self._execute('list', ['artist', 'musicbrainz_artistid', '']))
if not match and not found:
return
if len(match) > 1:
- self.log.debug('found close match for "%s": %s' %
- (artist, '/'.join(match)))
+ self.log.debug('found close match for "%s": %s', artist, '/'.join(match))
# Does not perform fuzzy matching on short and single word strings
# Only lowercased comparison
if ' ' not in artist.name and len(artist.name) < 8:
found = True
artist.add_alias(fuzz_art)
if artist.name != fuzz_art:
- self.log.debug('"%s" matches "%s".' % (fuzz_art, artist))
+ self.log.debug('"%s" matches "%s".', fuzz_art, artist)
continue
# SimaStr string __eq__ (not regular string comparison here)
if fzartist == fuzz_art:
found = True
artist.add_alias(fuzz_art)
- self.log.info('"%s" quite probably matches "%s" (SimaStr)' %
- (fuzz_art, artist))
+ self.log.info('"%s" quite probably matches "%s" (SimaStr)',
+ fuzz_art, artist)
if found:
if artist.aliases:
- self.log.debug('Found: {}'.format('/'.join(list(artist.names)[:4])))
+ self.log.debug('Found: %s', '/'.join(list(artist.names)[:4]))
return artist
def fuzzy_find_track(self, artist, title):
if leven == 1:
pass
elif leven >= 0.79: # PARAM
- self.log.debug('title: "%s" should match "%s" (lr=%1.3f)' %
- (title_, title, leven))
+ self.log.debug('title: "%s" should match "%s" (lr=%1.3f)',
+ title_, title, leven)
else:
- self.log.debug('title: "%s" does not match "%s" (lr=%1.3f)' %
- (title_, title, leven))
+ self.log.debug('title: "%s" does not match "%s" (lr=%1.3f)',
+ title_, title, leven)
return []
return self.find('artist', artist, 'title', title_)
albums = []
for name in artist.names:
if len(artist.names) > 1:
- self.log.debug('Searching album for aliase: "{}"'.format(name))
+ self.log.debug('Searching album for aliase: "%s"', name)
kwalbart = {'albumartist':name, 'artist':name}
for album in self.list('album', 'albumartist', artist):
if album and album not in albums:
for album in self.list('album', 'artist', artist):
album_trks = [trk for trk in self.find('album', album)]
if 'Various Artists' in [tr.albumartist for tr in album_trks]:
- self.log.debug('Discarding {0} ("Various Artists" set)'.format(album))
+ self.log.debug('Discarding %s ("Various Artists" set)', album)
continue
arts = set([trk.artist for trk in album_trks])
if len(set(arts)) < 2: # TODO: better heuristic, use a ratio instead
albums.append(Album(name=album, **kwalbart))
elif album and album not in albums:
self.log.debug('"{0}" probably not an album of "{1}"'.format(
- album, artist) + '({0})'.format('/'.join(arts)))
+ album, artist) + '({0})'.format('/'.join(arts)))
return albums
def monitor(self):
if 'idle' in self._client._pending:
self._client.noidle()
elif self._client._pending:
- self.log.warning('pending commands: {}'.format(self._client._pending))
+ self.log.warning('pending commands: %s', self._client._pending)
def remove(self, position=0):
self.delete(position)
if Artist.use_mbid:
if 'MUSICBRAINZ_ARTISTID' not in self._client.tagtypes():
self.log.warning('Use of MusicBrainzIdentifier is set but MPD is '
- 'not providing related metadata')
+ 'not providing related metadata')
self.log.info(self._client.tagtypes())
self.log.warning('Disabling MusicBrainzIdentifier')
Artist.use_mbid = False
return False
queue = self.player.queue
queue_trigger = self.config.getint('sima', 'queue_length')
- self.log.debug('Currently {0} track(s) ahead. (target {1})'.format(
- len(queue), queue_trigger))
+ self.log.debug('Currently %s track(s) ahead. (target %s)', len(queue), queue_trigger)
if len(queue) < queue_trigger:
return True
return False
def queue(self):
to_add = list()
for plugin in self.plugins:
- self.log.info('running {}'.format(plugin))
+ self.log.info('running %s', plugin)
pl_candidates = getattr(plugin, 'callback_need_track')()
if pl_candidates:
to_add.extend(pl_candidates)
continue
except PlayerUnHandledError as err:
#TODO: unhandled Player exceptions
- self.log.warning('Unhandled player exception: %s' % err)
+ self.log.warning('Unhandled player exception: %s', err)
self.log.info('Got reconnected')
break
self.foreach_plugin('start')
self.player.connect()
self.foreach_plugin('start')
except (PlayerError, PlayerUnHandledError) as err:
- self.log.warning('Player: {}'.format(err))
+ self.log.warning('Player: %s', err)
self.reconnect_player()
while 42:
try:
self.loop()
except PlayerUnHandledError as err:
#TODO: unhandled Player exceptions
- self.log.warning('Unhandled player exception: {}'.format(err))
+ self.log.warning('Unhandled player exception: %s', err)
del self.player
self.player = PlayerClient()
time.sleep(10)
except PlayerError as err:
- self.log.warning('Player error: %s' % err)
+ self.log.warning('Player error: %s', err)
self.reconnect_player()
del self.changed
self.changed = self.player.monitor()
else: # first iteration goes through else
self.changed = ['playlist', 'player', 'skipped']
- self.log.debug('changed: {}'.format(', '.join(self.changed)))
+ self.log.debug('changed: %s', ', '.join(self.changed))
if 'playlist' in self.changed:
self.foreach_plugin('callback_playlist')
- if ('player' in self.changed
- or 'options' in self.changed):
+ if 'player' in self.changed or 'options' in self.changed:
self.foreach_plugin('callback_player')
if 'database' in self.changed:
self.foreach_plugin('callback_player_database')
if 'skipped' in self.changed:
if self.player.state == 'play':
- self.log.info('Playing: {}'.format(self.player.current))
+ self.log.info('Playing: %s', self.player.current)
self.add_history()
self.foreach_plugin('callback_next_song')
if self.need_tracks():
import logging
import sys
-from importlib import __import__
+from importlib import __import__ as sima_import
from os.path import isfile
##
plugin = plugin.strip(' \n')
module = 'sima.plugins.{0}.{1}'.format(source, plugin.lower())
try:
- mod_obj = __import__(module, fromlist=[plugin])
+ mod_obj = sima_import(module, fromlist=[plugin])
except ImportError as err:
logger.error('Failed to load "{}" plugin\'s module: '.format(plugin) +
'{0} ({1})'.format(module, err))
logfile = config.get('log', 'logfile', fallback=None)
verbosity = config.get('log', 'verbosity')
set_logger(verbosity, logfile)
- logger.debug('Command line say: {0}'.format(sopt.options))
+ logger.debug('Command line say: %s', sopt.options)
# Create Database
db_file = config.get('sima', 'db_file')
if (sopt.options.get('create_db', None)
- or not isfile(db_file)):
- logger.info('Creating database in "{}"'.format(db_file))
+ or not isfile(db_file)):
+ logger.info('Creating database in "%s"', db_file)
open(db_file, 'a').close()
SimaDB(db_path=db_file).create_db()
if sopt.options.get('create_db', None):
def main():
"""Entry point"""
nfo = dict({'version': info.__version__,
- 'prog': 'sima'})
+ 'prog': 'sima'})
# StartOpt gathers options from command line call (in StartOpt().options)
sopt = StartOpt(nfo)
run(sopt)
-# pylint: disable=missing-docstring
is_uuid4(kwargs.get('mbid'))
self.__mbid = kwargs.pop('mbid').lower()
except WrongUUID4:
- self.log.warning('Wrong mbid {}:{}'.format(self.__name,
- kwargs.get('mbid')))
+ self.log.warning('Wrong mbid %s:%s', self.__name,
+ kwargs.get('mbid'))
# mbid immutable as hash rests on
self.__dict__.update(**kwargs)
# standard library import
import logging
-from difflib import get_close_matches
from itertools import dropwhile
# local import
-from .meta import Artist
-from .simastr import SimaStr
-from ..utils.leven import levenshtein_ratio
def blacklist(artist=False, album=False, track=False):
#pylint: disable=C0111,W0212
@property
def artists(self):
+ #pylint: disable=C0111
raise NotImplementedError
@property
def state(self):
+ #pylint: disable=C0111
raise NotImplementedError
@property
def current(self):
+ #pylint: disable=C0111
raise NotImplementedError
@property
def queue(self):
+ #pylint: disable=C0111
raise NotImplementedError
@property
def playlist(self):
+ #pylint: disable=C0111
raise NotImplementedError
# VIM MODLINE
if cls.__doc__:
doc = cls.__doc__.strip(' \n').splitlines()[0]
return {'name': cls.__name__,
- 'doc': doc,
- }
+ 'doc': doc,}
def __init__(self, daemon):
self.log = daemon.log
from datetime import (datetime, timedelta)
from os.path import dirname, isdir
from os import (access, W_OK, F_OK)
-from shutil import copyfile
class SimaDBError(Exception):
# Controls directory access
if not isdir(dirname(db_path)):
raise SimaDBAccessError('Not a regular directory: "%s"' %
- dirname(db_path))
+ dirname(db_path))
if not access(dirname(db_path), W_OK):
raise SimaDBAccessError('No write access to "%s"' % dirname(db_path))
# Is a file but no write access
return connection
def get_artist(self, artist_name, mbid=None,
- with_connection=None, add_not=False):
+ with_connection=None, add_not=False):
"""get artist information from the database.
if not in database insert new entry."""
if with_connection:
self.close_database_connection(connection)
def get_album(self, track, mbid=None,
- with_connection=None, add_not=False):
+ with_connection=None, add_not=False):
"""
get album information from the database.
if not in database insert new entry.
yield artist
def get_bl_artist(self, artist_name,
- with_connection=None, add_not=None):
+ with_connection=None, add_not=None):
"""get blacklisted artist information from the database."""
if with_connection:
connection = with_connection
else:
connection = self.get_database_connection()
- art = self.get_artist(artist_name,
- with_connection=connection, add_not=add_not)
+ art = self.get_artist(artist_name, with_connection=connection,
+ add_not=add_not)
if not art:
return False
art_id = art[0]
rows = connection.execute("SELECT * FROM black_list WHERE artist = ?",
- (art_id,))
+ (art_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
self.close_database_connection(connection)
return False
connection.execute("INSERT INTO black_list (artist) VALUES (?)",
- (art_id,))
+ (art_id,))
connection.execute("UPDATE black_list SET updated = DATETIME('now')"
- " WHERE artist = ?", (art_id,))
+ " WHERE artist = ?", (art_id,))
connection.commit()
rows = connection.execute("SELECT * FROM black_list WHERE artist = ?",
- (art_id,))
+ (art_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
self.close_database_connection(connection)
return False
- def get_bl_album(self, track,
- with_connection=None, add_not=None):
+ def get_bl_album(self, track, with_connection=None, add_not=None):
"""get blacklisted album information from the database."""
if with_connection:
connection = with_connection
else:
connection = self.get_database_connection()
- album = self.get_album(track,
- with_connection=connection, add_not=add_not)
+ album = self.get_album(track, with_connection=connection,
+ add_not=add_not)
if not album:
return False
alb_id = album[0]
rows = connection.execute("SELECT * FROM black_list WHERE album = ?",
- (alb_id,))
+ (alb_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
self.close_database_connection(connection)
return False
connection.execute("INSERT INTO black_list (album) VALUES (?)",
- (alb_id,))
+ (alb_id,))
connection.execute("UPDATE black_list SET updated = DATETIME('now')"
- " WHERE album = ?", (alb_id,))
+ " WHERE album = ?", (alb_id,))
connection.commit()
rows = connection.execute("SELECT * FROM black_list WHERE album = ?",
- (alb_id,))
+ (alb_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
connection = with_connection
else:
connection = self.get_database_connection()
- track = self.get_track(track,
- with_connection=connection, add_not=add_not)
+ track = self.get_track(track, with_connection=connection,
+ add_not=add_not)
if not track:
return False
track_id = track[0]
rows = connection.execute("SELECT * FROM black_list WHERE track = ?",
- (track_id,))
+ (track_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
self.close_database_connection(connection)
return False
connection.execute("INSERT INTO black_list (track) VALUES (?)",
- (track_id,))
+ (track_id,))
connection.execute("UPDATE black_list SET updated = DATETIME('now')"
- " WHERE track = ?", (track_id,))
+ " WHERE track = ?", (track_id,))
connection.commit()
rows = connection.execute("SELECT * FROM black_list WHERE track = ?",
- (track_id,))
+ (track_id,))
for row in rows:
if not with_connection:
self.close_database_connection(connection)
"""Retrieve complete black list."""
connection = self.get_database_connection()
rows = connection.execute('SELECT black_list.rowid, artists.name'
- ' FROM artists INNER JOIN black_list'
- ' ON artists.id = black_list.artist')
+ ' FROM artists INNER JOIN black_list'
+ ' ON artists.id = black_list.artist')
yield ('Row ID', 'Actual black listed element', 'Extra information',)
yield ('',)
yield ('Row ID', 'Artist',)
else:
connection = self.get_database_connection()
connection.execute("UPDATE artists SET mbid = ? WHERE id = ?",
- (mbid, artist_id))
+ (mbid, artist_id))
connection.commit()
if not with_connection:
self.close_database_connection(connection)
"""Remove bl row id"""
connection = self.get_database_connection()
connection.execute('DELETE FROM black_list'
- ' WHERE black_list.rowid = ?', (rowid,))
+ ' WHERE black_list.rowid = ?', (rowid,))
connection.commit()
self.close_database_connection(connection)
connection.execute("INSERT INTO history (track) VALUES (?)",
(track_id,))
connection.execute("UPDATE history SET last_play = DATETIME('now') "
- " WHERE track = ?", (track_id,))
+ " WHERE track = ?", (track_id,))
connection.commit()
self.close_database_connection(connection)
"""Remove old entries in history"""
connection = self.get_database_connection()
connection.execute("DELETE FROM history WHERE last_play"
- " < datetime('now', '-%i hours')" % duration)
+ " < datetime('now', '-%i hours')" % duration)
connection.commit()
self.close_database_connection(connection)
"""Add db version"""
connection = self.get_database_connection()
connection.execute('INSERT INTO db_info (version, name) VALUES (?, ?)',
- (__DB_VERSION__, 'Sima DB'))
+ (__DB_VERSION__, 'Sima DB'))
connection.commit()
self.close_database_connection(connection)
name = 'Last.fm'
cache = False
stats = {'etag':0,
- 'ccontrol':0,
- 'total':0}
+ 'ccontrol':0,
+ 'total':0}
def __init__(self):
self.http = HttpClient(cache=self.cache, stats=self.stats)
"""Build payload
"""
payloads = dict({'similar': {'method':'artist.getsimilar',},
- 'top': {'method':'artist.gettoptracks',},
- 'track': {'method':'track.getsimilar',},
- 'info': {'method':'artist.getinfo',},
+ 'top': {'method':'artist.gettoptracks',},
+ 'track': {'method':'track.getsimilar',},
+ 'info': {'method':'artist.getinfo',},
})
payload = payloads.get(method)
payload.update(api_key=LFM.get('apikey'), format='json')
payload = self._forge_payload(artist)
# Construct URL
ans = self.http(self.root_url, payload)
- self._controls_answer(ans.json())
+ self._controls_answer(ans.json()) # pylint: disable=no-member
# Artist might be found be return no 'artist' list…
# cf. "Mulatu Astatqe" vs. "Mulatu Astatqé" with autocorrect=0
# json format is broken IMHO, xml is more consistent IIRC
# Here what we got:
# >>> {"similarartists":{"#text":"\n","artist":"Mulatu Astatqe"}}
# autocorrect=1 should fix it, checking anyway.
- simarts = ans.json().get('similarartists').get('artist')
+ simarts = ans.json().get('similarartists').get('artist') # pylint: disable=no-member
if not isinstance(simarts, list):
raise WSError('Artist found but no similarities returned')
- for art in ans.json().get('similarartists').get('artist'):
+ for art in ans.json().get('similarartists').get('artist'): # pylint: disable=no-member
yield Artist(name=art.get('name'), mbid=art.get('mbid', None))
def get_toptrack(self, artist=None):
"""
payload = self._forge_payload(artist, method='top')
ans = self.http(self.root_url, payload)
- self._controls_answer(ans.json())
- tops = ans.json().get('toptracks').get('track')
- art = {
- 'artist': artist.name,
- 'musicbrainz_artistid': artist.mbid,
- }
+ self._controls_answer(ans.json()) # pylint: disable=no-member
+ tops = ans.json().get('toptracks').get('track') # pylint: disable=no-member
+ art = {'artist': artist.name,
+ 'musicbrainz_artistid': artist.mbid,}
for song in tops:
for key in ['artist', 'streamable', 'listeners',
'url', 'image', '@attr']:
self.to_add = list()
self._cache = None
self._flush_cache()
- wrapper = {
- 'track': self._track,
- 'top': self._top,
- 'album': self._album,
- }
+ wrapper = {'track': self._track,
+ 'top': self._top,
+ 'album': self._album,}
self.queue_mode = wrapper.get(self.plugin_conf.get('queue_mode'))
self.ws = None
self.log.info('{0}: Flushing cache!'.format(name))
else:
self.log.info('{0}: Initialising cache!'.format(name))
- self._cache = {
- 'asearch': dict(),
- 'tsearch': dict(),
- }
+ self._cache = {'asearch': dict(),
+ 'tsearch': dict(),}
def _cleanup_cache(self):
"""Avoid bloated cache
candidate = []
for trk in [_ for _ in not_in_hist if _ not in black_list]:
# Should use albumartist heuristic as well
- if self.plugin_conf.getboolean('single_album'):
+ if self.plugin_conf.getboolean('single_album'): # pylint: disable=no-member
if (trk.album == self.player.current.album or
- trk.album in [tr.album for tr in self.to_add]):
+ trk.album in [tr.album for tr in self.to_add]):
self.log.debug('Found unplayed track ' +
- 'but from an album already queued: %s' % (trk))
+ 'but from an album already queued: %s', trk)
continue
candidate.append(trk)
if not candidate:
Look in player library for availability of similar artists in
similarities
"""
- dynamic = self.plugin_conf.getint('max_art')
+ dynamic = self.plugin_conf.getint('max_art') # pylint: disable=no-member
if dynamic <= 0:
dynamic = 100
results = list()
extra_arts = list()
ret_extra = list()
depth = 0
- while depth < self.plugin_conf.getint('depth'):
+ while depth < self.plugin_conf.getint('depth'): # pylint: disable=no-member
if len(history) == 0:
break
trk = history.popleft()
continue
extra_arts.append(trk.Artist)
depth += 1
- self.log.debug('EXTRA ARTS: {}'.format(
- '/'.join(map(str, extra_arts))))
+ self.log.debug('EXTRA ARTS: %s', '/'.join(map(str, extra_arts)))
for artist in extra_arts:
self.log.debug('Looking for artist similar '
'to "{}" as well'.format(artist))
if last_trk.Artist in ret_extra:
ret_extra.remove(last_trk.Artist)
if ret_extra:
- self.log.debug('similar artist(s) found: {}'.format(
- ' / '.join(map(str, MetaContainer(ret_extra)))))
+ self.log.debug('similar artist(s) found: %s',
+ ' / '.join(map(str, MetaContainer(ret_extra))))
return ret_extra
def get_local_similar_artists(self):
if not similar:
self.log.info('Got nothing from {0}!'.format(self.ws.name))
return []
- self.log.info('First five similar artist(s): {}...'.format(
- ' / '.join(map(str, list(similar)[:5]))))
+ self.log.info('First five similar artist(s): %s...',
+ ' / '.join(map(str, list(similar)[:5])))
self.log.info('Looking availability in music library')
ret = MetaContainer(self.get_artists_from_player(similar))
if ret:
- self.log.debug('regular found in library: {}'.format(
- ' / '.join(map(str, ret))))
+ self.log.debug('regular found in library: %s',
+ ' / '.join(map(str, ret)))
else:
self.log.debug('Got nothing similar from library!')
ret_extra = None
if len(self.history) >= 2:
- if self.plugin_conf.getint('depth') > 1:
+ if self.plugin_conf.getint('depth') > 1: # pylint: disable=no-member
ret_extra = self.get_recursive_similar_artist()
if ret_extra:
# get them reorg to pick up best element
else:
ret_extra = MetaContainer(ret_extra[:max(4, len(ret))//2])
if ret_extra:
- self.log.debug('extra found in library: {}'.format(
- ' / '.join(map(str, ret_extra))))
+ self.log.debug('extra found in library: %s',
+ ' / '.join(map(str, ret_extra)))
ret = ret | ret_extra
if not ret:
self.log.warning('Got nothing from music library.')
"""
self.to_add = list()
nb_album_add = 0
- target_album_to_add = self.plugin_conf.getint('album_to_add')
+ target_album_to_add = self.plugin_conf.getint('album_to_add') # pylint: disable=no-member
for artist in artists:
self.log.info('Looking for an album to add for "%s"...' % artist)
albums = self.player.search_albums(artist)
# str conversion while Album type is not propagated
albums = [str(album) for album in albums]
if albums:
- self.log.debug('Albums candidate: {0:s}'.format(
- ' / '.join(albums)))
+ self.log.debug('Albums candidate: %s', ' / '.join(albums))
else: continue
# albums yet in history for this artist
albums = set(albums)
# Good heuristic, at least enough to guess if the whole album is
# already queued.
if tracks[0] in self.player.queue:
- self.log.debug('"%s" already queued, skipping!' %
- tracks[0].album)
+ self.log.debug('"%s" already queued, skipping!', tracks[0].album)
continue
album_to_queue = album
if not album_to_queue:
- self.log.info('No album found for "%s"' % artist)
+ self.log.info('No album found for "%s"', artist)
continue
- self.log.info('{2} album candidate: {0} - {1}'.format(
- artist, album_to_queue, self.ws.name))
+ self.log.info('%s album candidate: %s - %s', self.ws.name, artist, album_to_queue)
nb_album_add += 1
self.to_add.extend(self.player.find_album(artist, album_to_queue))
if nb_album_add == target_album_to_add:
find top tracks for artists in artists list.
"""
self.to_add = list()
- nbtracks_target = self.plugin_conf.getint('track_to_add')
+ nbtracks_target = self.plugin_conf.getint('track_to_add') # pylint: disable=no-member
for artist in artists:
if len(self.to_add) == nbtracks_target:
return True
try:
titles = [t for t in self.ws.get_toptrack(artist)]
except WSError as err:
- self.log.warning('{0}: {1}'.format(self.ws.name, err))
+ self.log.warning('%s: %s', self.ws.name, err)
for trk in titles:
found = self.player.fuzzy_find_track(artist, trk.title)
random.shuffle(found)
if found:
- self.log.debug('{0}'.format(found[0]))
+ self.log.debug('%s', found[0])
if self.filter_track(found):
break
"""Get some tracks for track queue mode
"""
artists = self.get_local_similar_artists()
- nbtracks_target = self.plugin_conf.getint('track_to_add')
+ nbtracks_target = self.plugin_conf.getint('track_to_add') # pylint: disable=no-member
for artist in artists:
- self.log.debug('Trying to find titles to add for "{!r}"'.format(
- artist))
+ self.log.debug('Trying to find titles to add for "%r"', artist)
found = self.player.find_track(artist)
random.shuffle(found)
if not found:
-# pylint: disable=missing-docstring
-# pylint: disable=missing-docstring
-# pylint: disable=missing-docstring
-# pylint: disable=missing-docstring
return
except ValueError:
self.log.warning('Bad value for consume, '
- 'expecting an integer, not "{}"'.format(target))
+ 'expecting an integer, not "%s"', target)
else:
self.target = int(target)
self.log.debug('Cropping at 15')
# local import
from ...lib.simafm import SimaFM
from ...lib.webserv import WebService
-from ...lib.cache import FileCache, DictCache
+from ...lib.cache import FileCache
class Lastfm(WebService):
self.mode = self.plugin_conf.get('flavour', None)
if self.mode not in ['pure', 'sensible']:
self.log.warning('Bad value for flavour, '
- '"{}" not in ["pure", "sensible"]'.format(self.mode))
+ '"%s" not in ["pure", "sensible"]', self.mode)
self.mode = 'pure'
def get_played_artist(self,):
# You should have received a copy of the GNU General Public License
# along with sima. If not, see <http://www.gnu.org/licenses/>.
#
-#
+# pylint: disable=bad-continuation
"""
Deal with configuration and data files.
import sys
from configparser import Error
-from os import (access, makedirs, environ, stat, chmod, W_OK, R_OK)
+from os import (access, makedirs, environ, stat, chmod, W_OK)
from os.path import (join, isdir, isfile, dirname, exists)
from stat import (S_IMODE, ST_MODE, S_IRWXO, S_IRWXG)
argparse.
"""
ok = True
- for op, ftochk in [('logfile', self.config.get('log','logfile')),
+ for op, ftochk in [('logfile', self.config.get('log', 'logfile')),
('pidfile', self.config.get('daemon', 'pidfile')),]:
if not ftochk:
continue
if isdir(ftochk):
- self.log.critical('Need a file not a directory: "{}"'.format(ftochk))
+ self.log.critical('Need a file not a directory: "%s"', ftochk)
ok = False
if not exists(ftochk):
# Is parent directory writable then
filedir = dirname(ftochk)
if not access(filedir, W_OK):
- self.log.critical('no write access to "{0}" ({1})'.format(filedir, op))
+ self.log.critical('no write access to "%s" (%s)', filedir, op)
ok = False
else:
if not access(ftochk, W_OK):
- self.log.critical('no write access to "{0}" ({1})'.format(ftochk, op))
+ self.log.critical('no write access to "%s" (%s)', ftochk, op)
ok = False
if not ok:
if exists(self.conf_file):
- self.log.warning('Try to check the configuration file: {}'.format(self.conf_file))
+ self.log.warning('Try to check the configuration file: %s', self.conf_file)
sys.exit(2)
def control_mod(self):
Controls conf file permissions.
"""
mode = S_IMODE(stat(self.conf_file)[ST_MODE])
- self.log.debug('file permission is: %o' % mode)
+ self.log.debug('file permission is: %o', mode)
if mode & S_IRWXO or mode & S_IRWXG:
self.log.warning('File is readable by "other" and/or' +
' "group" (actual permission %o octal).' %
"""Use MPD en.var. to set defaults"""
mpd_host, mpd_port, passwd = utils.get_mpd_environ()
if mpd_host:
- self.log.info('Env. variable MPD_HOST set to "%s"' % mpd_host)
+ self.log.info('Env. variable MPD_HOST set to "%s"', mpd_host)
self.config['MPD'].update(host=mpd_host)
if passwd:
self.log.info('Env. variable MPD_HOST contains password.')
self.config['MPD'].update(password=passwd)
if mpd_port:
- self.log.info('Env. variable MPD_PORT set to "%s".' % mpd_port)
+ self.log.info('Env. variable MPD_PORT set to "%s".', mpd_port)
self.config['MPD'].update(port=mpd_port)
def init_config(self):
if not isfile(self.conf_file):
return
- self.log.info('Loading configuration from: %s' % self.conf_file)
+ self.log.info('Loading configuration from: %s', self.conf_file)
self.control_mod()
try: