]> kaliko git repositories - mpd-goodies.git/blob - bin/mlast
Fixed protocol version check for mlast
[mpd-goodies.git] / bin / mlast
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 # SPDX-FileCopyrightText: 2009,2010,2012,2019 kaliko <kaliko@azylum.org>
4 # SPDX-License-Identifier: GPL-3.0-or-later
5
6 import argparse
7 import sys
8
9 from os.path import basename
10
11 import musicpd
12
13 VERSION = '0.1'
14
15
16 def unic(li):
17     my_set = set()
18     res = []
19     for _ in li:
20         if _ not in my_set:
21             res.append(_)
22             my_set.add(_)
23     return res
24
25
26 class MLast(musicpd.MPDClient):
27     script_info = dict({
28         'prog': basename(__file__),
29         'description': 'Show last music library changes.',
30         'epilog': 'Set MPD host/port in env. var'
31     })
32
33     def __init__(self):
34         """"""
35         musicpd.MPDClient.__init__(self)
36         self.args = self._get_args()
37         self._run()
38
39     def _get_args(self):
40         """"""
41         parser = argparse.ArgumentParser(**self.__class__.script_info)
42         parser.add_argument('--version', action='version',
43                             version='v%s' % VERSION)
44         parser.add_argument('n', type=int, nargs='?', default=5,
45                             help='how many items to fetch (defaults to 5)')
46         parser.add_argument('--add', action="store_true", default=False,
47                             help='Add items found to the queue')
48         group = parser.add_mutually_exclusive_group()
49         group.add_argument('-A', '--album', action="store_true", default=False,
50                            help='Look for lastest modified artists')
51         group.add_argument('-a', '--artist', action="store_true", default=False,
52                            help='Look for lastest modified albums')
53         group.add_argument('-t', '--track', action="store_true", default=False,
54                            help='Look for lastest modified tracks')
55         args = parser.parse_args()
56         if not (args.track or args.artist or args.album):
57             args.album = True
58         if args.track or args.artist:
59             self.offset = args.n
60         if args.album:
61             self.offset = 5*args.n
62         return args
63
64     def _filter_files(self, files):
65         filtered = []
66         manda_tags = ('album', 'artist', 'title')
67         for f in files:
68             if not all(k in f for k in manda_tags):
69                 print('Missing tags for {file}'.format(**f))
70                 continue
71             filtered.append(f)
72         return filtered
73
74     def _run(self):
75         """"""
76         bucket = []
77         self.connect()
78         version = self.mpd_version
79         if version[:4] in ['0.20', '0.19', '0.18', '0.17']:
80             print(f'MPD version might be < 0.21, need filter (got {version})')
81             sys.exit(1)
82         # Total number of tracks in library
83         nb_files = int(self.stats()['songs'])
84         upper_lim = nb_files
85         for i in range(self.offset, min(30*10, nb_files), self.offset):
86             # print('%d:%d' % (nb_files-i,upper_lim))
87             files = self.search('file', '', 'sort',
88                                 'Last-Modified', 'window', (nb_files-i, upper_lim))
89             upper_lim = nb_files-i
90             # print([f.get('file') for f in files])
91             # filter files with no tags
92             files = self._filter_files(files)
93             if self.args.album:
94                 # bucket = unic(bucket + [(f.get('artist'), f.get('album')) for f in files])
95                 _ = [(f.get('artist'), f.get('album')) for f in files]
96                 bucket = unic(bucket + _)
97             elif self.args.artist:
98                 _ = [(f.get('artist'),) for f in files]
99                 bucket = unic(bucket + _)
100             elif self.args.track:
101                 _ = [(f.get('artist'), f.get('album'), f.get('title'))
102                      for f in files]
103                 # bucket = unic(bucket + _)
104                 bucket = unic(_ + bucket)
105             if len(bucket) >= self.args.n:
106                 break
107         self.disconnect()
108         self.show(bucket)
109         sys.exit(0)
110
111     def show(self, results):
112         if self.args.artist:
113             tpl = '{}'
114         elif self.args.album:
115             tpl = '{} : {}'
116         elif self.args.track:
117             tpl = '{} : {} - {}'
118         for elem in results:
119             print(tpl.format(*elem))
120
121
122 # Script starts here
123 if __name__ == '__main__':
124     try:
125         MLast()
126     except KeyboardInterrupt:
127         sys.stdout.write('exit')
128
129 # VIM MODLINE
130 # vim: ai ts=4 sw=4 sts=4 expandtab