]> kaliko git repositories - mpd-goodies.git/commitdiff
Add mlast master
authorkaliko <kaliko@azylum.org>
Thu, 16 May 2019 16:41:39 +0000 (18:41 +0200)
committerkaliko <kaliko@azylum.org>
Thu, 16 May 2019 16:41:39 +0000 (18:41 +0200)
README.md
bin/mlast [new file with mode: 0755]

index 43aa84dc5b71fae078f3af80342b84ba87317baf..6be0ecf36c595f57a941ab2a05f49c086b4cdc99 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,10 +1,10 @@
 # MPD-GOODIES
 
-A collection of small commands to play with MusicPlayerDaemon:
+A collection of small commands to play with [MusicPlayerDaemon]:
 
   * Fading in/out over a specified time
   * Jumping to next album en queue.
-  * Last modified artist/album
+  * Last modified artist/album/tracks
   * Crop the queue
 
 [MusicPlayerDaemon]: https://www.musicpd.org/
diff --git a/bin/mlast b/bin/mlast
new file mode 100755 (executable)
index 0000000..b664aeb
--- /dev/null
+++ b/bin/mlast
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009,2010,2012,2019 kaliko <kaliko@azylum.org>
+#
+#   This program is free software: you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+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] not in ['0.21', '0.22']:
+            print('MPD version might be < 0.21, need filter')
+            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