mirror of
https://github.com/beetbox/beets.git
synced 2026-01-15 20:51:38 +01:00
Merge pull request #80 from dangmai/smartplaylist
Smart Playlist plugin
This commit is contained in:
commit
615b0decfa
3 changed files with 144 additions and 0 deletions
91
beetsplug/smartplaylist.py
Normal file
91
beetsplug/smartplaylist.py
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
# This file is part of beets.
|
||||
# Copyright 2013, Dang Mai <contact@dangmai.net>.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Generates smart playlists based on beets queries.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
from beets.plugins import BeetsPlugin
|
||||
from beets import config, ui
|
||||
from beets.util import normpath, syspath
|
||||
import os
|
||||
|
||||
# Global variables so that smartplaylist can detect database changes and run
|
||||
# only once before beets exits.
|
||||
database_changed = False
|
||||
library = None
|
||||
|
||||
|
||||
def update_playlists(lib):
|
||||
from beets.util.functemplate import Template
|
||||
print("Updating smart playlists...")
|
||||
playlists = config['smartplaylist']['playlists'].get(list)
|
||||
playlist_dir = config['smartplaylist']['playlist_dir'].get(unicode)
|
||||
relative_to = config['smartplaylist']['relative_to'].get()
|
||||
if relative_to:
|
||||
relative_to = normpath(relative_to)
|
||||
|
||||
for playlist in playlists:
|
||||
items = lib.items(playlist['query'])
|
||||
m3us = {}
|
||||
basename = playlist['name'].encode('utf8')
|
||||
# As we allow tags in the m3u names, we'll need to iterate through
|
||||
# the items and generate the correct m3u file names.
|
||||
for item in items:
|
||||
m3u_name = item.evaluate_template(Template(basename), lib=lib)
|
||||
if not (m3u_name in m3us):
|
||||
m3us[m3u_name] = []
|
||||
if relative_to:
|
||||
m3us[m3u_name].append(os.path.relpath(item.path, relative_to))
|
||||
else:
|
||||
m3us[m3u_name].append(item.path)
|
||||
# Now iterate through the m3us that we need to generate
|
||||
for m3u in m3us:
|
||||
m3u_path = normpath(os.path.join(playlist_dir, m3u))
|
||||
with open(syspath(m3u_path), 'w') as f:
|
||||
for path in m3us[m3u]:
|
||||
f.write(path + '\n')
|
||||
print("... Done")
|
||||
|
||||
|
||||
class SmartPlaylistPlugin(BeetsPlugin):
|
||||
def __init__(self):
|
||||
super(SmartPlaylistPlugin, self).__init__()
|
||||
self.config.add({
|
||||
'relative_to': None,
|
||||
'playlist_dir': u'.',
|
||||
'playlists': []
|
||||
})
|
||||
|
||||
def commands(self):
|
||||
def update(lib, opts, args):
|
||||
update_playlists(lib)
|
||||
spl_update = ui.Subcommand('splupdate',
|
||||
help='update the smart playlists')
|
||||
spl_update.func = update
|
||||
return [spl_update]
|
||||
|
||||
|
||||
@SmartPlaylistPlugin.listen('database_change')
|
||||
def handle_change(lib):
|
||||
global library
|
||||
global database_changed
|
||||
library = lib
|
||||
database_changed = True
|
||||
|
||||
|
||||
@SmartPlaylistPlugin.listen('cli_exit')
|
||||
def update():
|
||||
if database_changed:
|
||||
update_playlists(library)
|
||||
|
|
@ -59,6 +59,7 @@ disabled by default, but you can turn them on as described above.
|
|||
ihate
|
||||
convert
|
||||
info
|
||||
smartplaylist
|
||||
|
||||
Autotagger Extensions
|
||||
''''''''''''''''''''''
|
||||
|
|
@ -92,6 +93,7 @@ Interoperability
|
|||
* :doc:`mpdupdate`: Automatically notifies `MPD`_ whenever the beets library
|
||||
changes.
|
||||
* :doc:`importfeeds`: Keep track of imported files via ``.m3u`` playlist file(s) or symlinks.
|
||||
* :doc:`smartplaylist`: Generate smart playlists based on beets queries.
|
||||
|
||||
Miscellaneous
|
||||
'''''''''''''
|
||||
|
|
|
|||
51
docs/plugins/smartplaylist.rst
Normal file
51
docs/plugins/smartplaylist.rst
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
Smart Playlist Plugin
|
||||
=====================
|
||||
|
||||
``smartplaylist`` is a plugin to generate smart playlists in m3u format based on
|
||||
beets queries every time your library changes. This plugin is specifically
|
||||
created to work well with `MPD`_'s playlist functionality.
|
||||
|
||||
.. _MPD: http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki
|
||||
|
||||
To use it, enable the plugin by putting ``smartplaylist`` in the ``plugins``
|
||||
section in your ``config.yaml``. Then configure your smart playlists like the
|
||||
following example::
|
||||
|
||||
smartplaylist:
|
||||
relative_to: ~/Music
|
||||
playlist_dir: ~/.mpd/playlists
|
||||
playlists:
|
||||
- query: ''
|
||||
name: all.m3u
|
||||
|
||||
- query: 'artist:Beatles'
|
||||
name: beatles.m3u
|
||||
|
||||
If you intend to use this plugin to generate playlists for MPD, you should set
|
||||
``relative_to`` to your MPD music directory (by default, ``relative_to`` is
|
||||
``None``, and the absolute paths to your music files will be generated).
|
||||
|
||||
``playlist_dir`` is where the generated playlist files will be put.
|
||||
|
||||
You can generate as many playlists as you want by adding them to the
|
||||
``playlists`` section, using the normal querying format (see
|
||||
:doc:`/reference/query`) for ``query`` and the file name to be generated for
|
||||
``name`` (*note*: if you have existing files with the same names, you should
|
||||
back them up, as they will be overwritten when the plugin runs).
|
||||
|
||||
For more advanced usage, you can also specify metadata (see
|
||||
:doc:`/reference/pathformat/`) in the ``name`` field, for example::
|
||||
|
||||
- query: 'year::201(0|1)'
|
||||
name: 'ReleasedIn$year.m3u'
|
||||
|
||||
This will query all the songs in 2010 and 2011, and generate the 2 playlist
|
||||
files `ReleasedIn2010.m3u` and `ReleasedIn2011.m3u` using those songs.
|
||||
|
||||
If you add a smart playlist to your ``config.yaml`` file and don't want to wait
|
||||
until the next time your library changes for ``smartplugin`` to run, you can
|
||||
invoke it manually from the command-line::
|
||||
|
||||
$ beet splupdate
|
||||
|
||||
which will generate your new smart playlists.
|
||||
Loading…
Reference in a new issue