mirror of
https://github.com/beetbox/beets.git
synced 2026-01-05 23:43:31 +01:00
Merge branch 'missing' of https://github.com/pedros/beets
Conflicts: docs/plugins/index.rst
This commit is contained in:
commit
e1f7027abc
3 changed files with 251 additions and 2 deletions
150
beetsplug/missing.py
Normal file
150
beetsplug/missing.py
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2013, Pedro Silva.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
|
||||
'''list missing tracks
|
||||
'''
|
||||
import logging
|
||||
|
||||
from beets.autotag import hooks
|
||||
from beets.library import Item
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets.ui import decargs, print_obj, Subcommand
|
||||
|
||||
plugin = 'missing'
|
||||
log = logging.getLogger('beets')
|
||||
|
||||
|
||||
def _missing_count(album):
|
||||
'''Return number of missing items in `album`.
|
||||
'''
|
||||
return album.tracktotal - len([i for i in album.items()])
|
||||
|
||||
|
||||
def _missing(album):
|
||||
'''Query MusicBrainz to determine items missing from `album`.
|
||||
'''
|
||||
item_mbids = map(lambda x: x.mb_trackid, album.items())
|
||||
|
||||
if len([i for i in album.items()]) < album.tracktotal:
|
||||
# fetch missing items
|
||||
# TODO: Implement caching that without breaking other stuff
|
||||
album_info = hooks._album_for_id(album.mb_albumid)
|
||||
for track_info in getattr(album_info, 'tracks', []):
|
||||
if track_info.track_id not in item_mbids:
|
||||
item = _item(track_info, album_info, album.id)
|
||||
log.debug('{}: track {} in album {}'
|
||||
.format(plugin,
|
||||
track_info.track_id,
|
||||
album_info.album_id))
|
||||
yield item
|
||||
|
||||
|
||||
def _item(track_info, album_info, album_id):
|
||||
'''Build and return `item` from `track_info` and `album info`
|
||||
objects. `item` is missing what fields cannot be obtained from
|
||||
MusicBrainz alone (encoder, rg_track_gain, rg_track_peak,
|
||||
rg_album_gain, rg_album_peak, original_year, original_month,
|
||||
original_day, length, bitrate, format, samplerate, bitdepth,
|
||||
channels, mtime.)
|
||||
'''
|
||||
t = track_info
|
||||
a = album_info
|
||||
|
||||
return Item({'album_id': album_id,
|
||||
'album': a.album,
|
||||
'albumartist': a.artist,
|
||||
'albumartist_credit': a.artist_credit,
|
||||
'albumartist_sort': a.artist_sort,
|
||||
'albumdisambig': a.albumdisambig,
|
||||
'albumstatus': a.albumstatus,
|
||||
'albumtype': a.albumtype,
|
||||
'artist': t.artist,
|
||||
'artist_credit': t.artist_credit,
|
||||
'artist_sort': t.artist_sort,
|
||||
'asin': a.asin,
|
||||
'catalognum': a.catalognum,
|
||||
'comp': a.va,
|
||||
'country': a.country,
|
||||
'day': a.day,
|
||||
'disc': t.medium,
|
||||
'disctitle': t.disctitle,
|
||||
'disctotal': a.mediums,
|
||||
'label': a.label,
|
||||
'language': a.language,
|
||||
'length': t.length,
|
||||
'mb_albumid': a.album_id,
|
||||
'mb_artistid': t.artist_id,
|
||||
'mb_releasegroupid': a.releasegroup_id,
|
||||
'mb_trackid': t.track_id,
|
||||
'media': a.media,
|
||||
'month': a.month,
|
||||
'script': a.script,
|
||||
'title': t.title,
|
||||
'track': t.index,
|
||||
'tracktotal': len(a.tracks),
|
||||
'year': a.year})
|
||||
|
||||
|
||||
class MissingPlugin(BeetsPlugin):
|
||||
'''List missing tracks
|
||||
'''
|
||||
def __init__(self):
|
||||
super(MissingPlugin, self).__init__()
|
||||
|
||||
self.config.add({'format': None})
|
||||
self.config.add({'count': False})
|
||||
self.config.add({'total': False})
|
||||
|
||||
self._command = Subcommand('missing',
|
||||
help=__doc__,
|
||||
aliases=['miss'])
|
||||
|
||||
self._command.parser.add_option('-f', '--format', dest='format',
|
||||
action='store', type='string',
|
||||
help='print with custom FORMAT',
|
||||
metavar='FORMAT')
|
||||
|
||||
self._command.parser.add_option('-c', '--count', dest='count',
|
||||
action='store_true',
|
||||
help='count missing tracks per album')
|
||||
|
||||
self._command.parser.add_option('-t', '--total', dest='total',
|
||||
action='store_true',
|
||||
help='count total of missing tracks')
|
||||
|
||||
def commands(self):
|
||||
def _miss(lib, opts, args):
|
||||
self.config.set_args(opts)
|
||||
fmt = self.config['format'].get()
|
||||
count = self.config['count'].get()
|
||||
total = self.config['total'].get()
|
||||
|
||||
albums = lib.albums(decargs(args))
|
||||
if total:
|
||||
print(sum([_missing_count(a) for a in albums]))
|
||||
return
|
||||
|
||||
for album in albums:
|
||||
if count:
|
||||
missing = _missing_count(album)
|
||||
if missing:
|
||||
fmt = "$album: {}".format(missing)
|
||||
print_obj(album, lib, fmt=fmt)
|
||||
continue
|
||||
|
||||
for item in _missing(album):
|
||||
print_obj(item, lib, fmt=fmt)
|
||||
|
||||
self._command.func = _miss
|
||||
return [self._command]
|
||||
|
|
@ -61,7 +61,8 @@ disabled by default, but you can turn them on as described above.
|
|||
info
|
||||
smartplaylist
|
||||
mbsync
|
||||
|
||||
missing
|
||||
|
||||
Autotagger Extensions
|
||||
''''''''''''''''''''''
|
||||
|
||||
|
|
@ -110,7 +111,8 @@ Miscellaneous
|
|||
* :doc:`convert`: Transcode music and embed album art while exporting to
|
||||
a different directory.
|
||||
* :doc:`info`: Print music files' tags to the console.
|
||||
|
||||
* :doc:`missing`: List missing tracks.
|
||||
|
||||
.. _MPD: http://mpd.wikia.com/
|
||||
.. _MPD clients: http://mpd.wikia.com/wiki/Clients
|
||||
|
||||
|
|
|
|||
97
docs/plugins/missing.rst
Normal file
97
docs/plugins/missing.rst
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
Missing Plugin
|
||||
==============
|
||||
|
||||
This plugin adds a new command, ``missing`` or ``miss``, which finds
|
||||
and lists, for every album in your collection, which tracks are
|
||||
missing. Listing missing files requires one network call to
|
||||
MusicBrainz.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Enable the plugin by putting ``missing`` on your ``plugins`` line in
|
||||
:doc:`config file </reference/config>`::
|
||||
|
||||
plugins:
|
||||
missing
|
||||
...
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
The plugin accepts the following configuration directives, either in
|
||||
your configuration file::
|
||||
|
||||
missing:
|
||||
format: FMTSTR
|
||||
count: bool
|
||||
total: bool
|
||||
|
||||
or in the command-line::
|
||||
|
||||
$ beet missing --help
|
||||
Usage: beet missing [options]
|
||||
|
||||
Options:
|
||||
-h, --help show this help message and exit
|
||||
-f FORMAT, --format=FORMAT
|
||||
print with custom FORMAT
|
||||
-c, --count count missing tracks per album
|
||||
-t, --total count total of missing tracks
|
||||
|
||||
|
||||
format
|
||||
~~~~~~
|
||||
|
||||
The ``format`` option (default: ``None``) lets you specify a specific
|
||||
format with which to print every track. This uses the same template
|
||||
syntax as beets’ :doc:`path formats </reference/pathformat>`. The usage
|
||||
is inspired by, and therefore similar to, the :ref:`list <list-cmd>`
|
||||
command.
|
||||
|
||||
count
|
||||
~~~~~
|
||||
|
||||
The ``count` option (default: ``False``) prints a count of missing
|
||||
tracks per album, with ``format`` hard-coded to ``'$album: $count'``.
|
||||
|
||||
total
|
||||
~~~~~
|
||||
|
||||
The ``total`` option (default: ``False``) prints a single
|
||||
count of missing tracks in all albums
|
||||
|
||||
|
||||
Examples
|
||||
-------------------------
|
||||
|
||||
List all missing tracks in your collection::
|
||||
|
||||
beet missing
|
||||
|
||||
List all missing tracks from 2008::
|
||||
|
||||
beet missing year:2008
|
||||
|
||||
Print out a unicode histogram of the missing track years using `spark`_::
|
||||
|
||||
beet missing -f '$year' | spark
|
||||
▆▁▆█▄▇▇▄▇▇▁█▇▆▇▂▄█▁██▂█▁▁██▁█▂▇▆▂▇█▇▇█▆▆▇█▇█▇▆██▂▇
|
||||
|
||||
Print out a listing of all albums with missing tracks, and respective counts::
|
||||
|
||||
beet missing -c
|
||||
|
||||
Print out a count of the total number of missing tracks::
|
||||
|
||||
beet missing -t
|
||||
|
||||
|
||||
TODO
|
||||
----
|
||||
|
||||
- Add caching.
|
||||
|
||||
--------------
|
||||
|
||||
.. _spark: https://github.com/holman/spark
|
||||
Loading…
Reference in a new issue