#!/usr/bin/env python3 # -*- coding: utf-8 -*- # SPDX-FileCopyrightText: 2009,2010,2012,2019 kaliko # SPDX-License-Identifier: GPL-3.0-or-later import argparse import sys from os.path import basename import musicpd VERSION = '0.1' def unic(li): my_set = set() res = [] for _ in li: if _ not in my_set: res.append(_) my_set.add(_) return res class MLast(musicpd.MPDClient): script_info = dict({ 'prog': basename(__file__), 'description': 'Show last music library changes.', 'epilog': 'Set MPD host/port in env. var' }) def __init__(self): """""" musicpd.MPDClient.__init__(self) self.args = self._get_args() self._run() def _get_args(self): """""" parser = argparse.ArgumentParser(**self.__class__.script_info) parser.add_argument('--version', action='version', version='v%s' % VERSION) parser.add_argument('n', type=int, nargs='?', default=5, help='how many items to fetch (defaults to 5)') parser.add_argument('--add', action="store_true", default=False, help='Add items found to the queue') group = parser.add_mutually_exclusive_group() group.add_argument('-A', '--album', action="store_true", default=False, help='Look for lastest modified artists') group.add_argument('-a', '--artist', action="store_true", default=False, help='Look for lastest modified albums') group.add_argument('-t', '--track', action="store_true", default=False, help='Look for lastest modified tracks') args = parser.parse_args() if not (args.track or args.artist or args.album): args.album = True if args.track or args.artist: self.offset = args.n if args.album: self.offset = 5*args.n return args def _filter_files(self, files): filtered = [] manda_tags = ('album', 'artist', 'title') for f in files: if not all(k in f for k in manda_tags): print('Missing tags for {file}'.format(**f)) continue filtered.append(f) return filtered def _run(self): """""" bucket = [] self.connect() version = self.mpd_version if version[:4] in ['0.20', '0.19', '0.18', '0.17']: print(f'MPD version might be < 0.21, need filter (got {version})') sys.exit(1) # Total number of tracks in library nb_files = int(self.stats()['songs']) upper_lim = nb_files for i in range(self.offset, min(30*10, nb_files), self.offset): # print('%d:%d' % (nb_files-i,upper_lim)) files = self.search('file', '', 'sort', 'Last-Modified', 'window', (nb_files-i, upper_lim)) upper_lim = nb_files-i # print([f.get('file') for f in files]) # filter files with no tags files = self._filter_files(files) if self.args.album: # bucket = unic(bucket + [(f.get('artist'), f.get('album')) for f in files]) _ = [(f.get('artist'), f.get('album')) for f in files] bucket = unic(bucket + _) elif self.args.artist: _ = [(f.get('artist'),) for f in files] bucket = unic(bucket + _) elif self.args.track: _ = [(f.get('artist'), f.get('album'), f.get('title')) for f in files] # bucket = unic(bucket + _) bucket = unic(_ + bucket) if len(bucket) >= self.args.n: break self.disconnect() self.show(bucket) sys.exit(0) def show(self, results): if self.args.artist: tpl = '{}' elif self.args.album: tpl = '{} : {}' elif self.args.track: tpl = '{} : {} - {}' for elem in results: print(tpl.format(*elem)) # Script starts here if __name__ == '__main__': try: MLast() except KeyboardInterrupt: sys.stdout.write('exit') # VIM MODLINE # vim: ai ts=4 sw=4 sts=4 expandtab