translate plugin documentation

This commit is contained in:
Adrian Sampson 2011-09-17 11:04:51 -07:00
parent 3def27a96f
commit 2f8370669e
8 changed files with 512 additions and 3 deletions

View file

@ -1,5 +1,5 @@
Introduction
============
Guides
======
Tutorial stuff

View file

@ -171,7 +171,7 @@ also implicitly joined by ANDs: a track must match *all* criteria in order to
match the query.) To narrow a search term to a particular metadata field, just
put the field before the term, separated by a : character. So ``album:bird``
only looks for ``bird`` in the "album" field of your songs. (Need to know more?
:doc:`/ref/queries/` will answer all your questions.)
:doc:`/reference/query/` will answer all your questions.)
The ``beet list`` command has another useful option worth mentioning, ``-a``,
which searches for albums instead of songs::

View file

@ -11,3 +11,4 @@ Contents
guides/index
reference/index
plugins/index

125
docs/plugins/bpd.rst Normal file
View file

@ -0,0 +1,125 @@
BPD Plugin
==========
BPD is a music player using music from a beets library. It runs as a daemon and
implements the MPD protocol, so it's compatible with all the great MPD clients
out there. I'm using `Theremin`_, `gmpc`_, `Sonata`_, and `Ario`_ successfully.
.. _Theremin: https://theremin.sigterm.eu/
.. _gmpc: http://gmpc.wikia.com/wiki/Gnome_Music_Player_Client
.. _Sonata: http://sonata.berlios.de/
.. _Ario: http://ario-player.sourceforge.net/
Dependencies
------------
Before you can use BPD, you'll need the media library called GStreamer (along
with its Python bindings) on your system.
* On Mac OS X, you should use `MacPorts`_ and run ``port install
py26-gst-python``. (Note that you'll almost certainly need the Mac OS X
Developer Tools.)
* On Linux, it's likely that you already have gst-python. (If not, your
distribution almost certainly has a package for it.)
* On Windows, you may want to try `GStreamer WinBuilds`_ (cavet emptor: I
haven't tried this).
.. _MacPorts: http://www.macports.org/
.. _GStreamer WinBuilds: http://www.gstreamer-winbuild.ylatuya.es/
Using and Configuring
---------------------
BPD is a plugin for beets. It comes with beets, but it's disabled by default. To
enable it, you'll need to edit your ``.beetsconfig`` file and add the line
``plugins: bpd``. Like so::
[beets]
plugins: bpd
Then, you can run BPD by invoking::
$ beet bpd
Fire up your favorite MPD client to start playing music. The MPD site has `a
long list of available clients`_. Here are my favorites:
.. _a long list of available clients: http://mpd.wikia.com/wiki/Clients
* Linux: `gmpc`_, `Sonata`_
* Mac: `Theremin`_
* Windows: I don't know. Get in touch if you have a recommendation.
* iPhone/iPod touch: `MPoD`_
.. _MPoD: http://www.katoemba.net/makesnosenseatall/mpod/
One nice thing about MPD's (and thus BPD's) client-server architecture is that
the client can just as easily on a different computer from the server as it can
be run locally. Control your music from your laptop (or phone!) while it plays
on your headless server box. Rad!
To configure the BPD server, add a ``[bpd]`` section to your ``.beetsconfig``
file. The configuration values, which are pretty self-explanatory, are ``host``,
``port``, and ``password``. Here's an example::
[bpd]
host: 127.0.0.1
port: 6600
password: seekrit
Implementation Notes
--------------------
In the real MPD, the user can browse a music directory as it appears on disk. In
beets, we like to abstract away from the directory structure. Therefore, BPD
creates a "virtual" directory structure (artist/album/track) to present to
clients. This is static for now and cannot be reconfigured like the real on-disk
directory structure can. (Note that an obvious solution to this is just string
matching on items' destination, but this requires examining the entire library
Python-side for every query.)
We don't currently support versioned playlists. Many clients, however, use
plchanges instead of playlistinfo to get the current playlist, so plchanges
contains a dummy implementation that just calls playlistinfo.
The ``stats`` command always send zero for ``playtime``, which is supposed to
indicate the amount of time the server has spent playing music. BPD doesn't
currently keep track of this. Also, because database updates aren't yet
supported, ``db_update`` is just the time the server was started.
Unimplemented Commands
----------------------
These are the commands from `the MPD protocol`_ that have not yet been
implemented in BPD.
.. _the MPD protocol: http://mpd.wikia.com/wiki/MusicPlayerDaemonCommands
Database:
* update
Saved playlists:
* playlistclear
* playlistdelete
* playlistmove
* playlistadd
* playlistsearch
* listplaylist
* listplaylistinfo
* playlistfind
* rm
* save
* load
* rename
Deprecated:
* playlist
* volume

46
docs/plugins/embedart.rst Normal file
View file

@ -0,0 +1,46 @@
EmbedArt Plugin
===============
Typically, beets stores album art in a "file on the side": along with each
album, there is a file (named "cover.jpg" by default) that stores the album art.
You might want to embed the album art directly into each file's metadata. While
this will take more space than the external-file approach, it is necessary for
displaying album art in some media players (iPods, for example).
This plugin was added in beets 1.0b8.
Embedding Art Automatically
---------------------------
To automatically embed discovered album art into imported files, just
:doc:`enable the plugin </plugins/index>`. Art will be embedded after each album
is added to the library.
This behavior can be disabled with the ``autoembed`` config option (see below).
Manually Embedding and Extracting Art
-------------------------------------
The ``embedart`` plugin provides a couple of commands for manually managing
embedded album art:
* ``beet embedart IMAGE QUERY``: given an image file and a query matching an
album, embed the image into the metadata of every track on the album.
* ``beet extractart [-o FILE] QUERY``: extracts the image from an item matching
the query and stores it in a file. You can specify the destination file using
the ``-o`` option, but leave off the extension: it will be chosen
automatically. The destination filename defaults to ``cover`` if it's not
specified.
* ``beet clearart QUERY``: removes all embedded images from all items matching
the query. (Use with caution!)
Configuring
-----------
The plugin has one configuration option, ``autoembed``, which lets you disable
automatic album art embedding. To do so, add this to your ``~/.beetsconfig``::
[embedart]
autoembed: no

248
docs/plugins/index.rst Normal file
View file

@ -0,0 +1,248 @@
Plugins
=======
As of the 1.0b3 release, beets started supporting plugins to modularize its
functionality and allow other developers to add new functionality. Plugins can
add new commands to the command-line interface, respond to events in beets, and
augment the autotagger.
Using Plugins
-------------
To use a plugin, you have two options:
* Make sure it's in the Python path (known as `sys.path` to developers). This
just means the plugin has to be installed on your system (e.g., with a
`setup.py` script or a command like `pip` or `easy_install`).
* Set the `pythonpath` config variable to point to the directory containing the
plugin. (See :doc:`/reference/cli`.)
Then, set the `plugins` option in your `~/.beetsconfig` file, like so::
[beets]
plugins = mygreatplugin someotherplugin
The value for `plugins` should be a space-separated list of plugin module names.
.. _included-plugins:
Plugins Included With Beets
---------------------------
There are a few plugins that are included with the beets distribution. They're
disabled by default, but you can turn them on as described above:
.. toctree::
:maxdepth: 1
lastid
bpd
mpdupdate
embedart
.. _other-plugins:
Other Plugins
-------------
Here are a few of the plugins written by the beets community:
* `beets-replaygain`_ can analyze and store !ReplayGain normalization
information.
* `beets-lyrics`_ searches Web repositories for song lyrics and adds them to your files.
* `beetFs`_ is a FUSE filesystem for browsing the music in your beets library.
(Might be out of date.)
* `Beet-MusicBrainz-Collection`_ lets you add albums from your library to your
!MusicBrainz `"music collection"`_.
* `A cmus plugin`_ integrates with the `cmus`_ console music player.
.. _beets-replaygain: https://github.com/Lugoues/beets-replaygain/
.. _beets-lyrics: https://github.com/Lugoues/beets-lyrics/
.. _beetFs: http://code.google.com/p/beetfs/
.. _Beet-MusicBrainz-Collection:
https://github.com/jeffayle/Beet-MusicBrainz-Collection/
.. _"music collection": http://musicbrainz.org/show/collection/
.. _A cmus plugin:
https://github.com/coolkehon/beets/blob/master/beetsplug/cmus.py
.. _cmus: http://cmus.sourceforge.net/
Writing Plugins
---------------
A beets plugin is just a Python module inside the ``beetsplug`` namespace
package. (Check out this `Stack Overflow question about namespace packages`_ if
you haven't heard of them.) So, to make one, create a directory called
``beetsplug`` and put two files in it: one called ``__init__.py`` and one called
``myawesomeplugin.py`` (but don't actually call it that). Your directory
structure should look like this::
beetsplug/
__init__.py
myawesomeplugin.py
.. _Stack Overflow question about namespace packages:
http://stackoverflow.com/questions/1675734/how-do-i-create-a-namespace-package-in-python/1676069#1676069
Then, you'll need to put this stuff in ``__init__.py`` to make ``beetsplug`` a
namespace package::
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
That's all for ``__init__.py``; you can can leave it alone. The meat of your
plugin goes in ``myawesomeplugin.py``. There, you'll have to import the
``beets.plugins`` module and define a subclass of the ``BeetsPlugin`` class
found therein. Here's a skeleton of a plugin file::
from beets.plugins import BeetsPlugin
class MyPlugin(BeetsPlugin):
pass
Once you have your ``BeetsPlugin`` subclass, there's a variety of things your
plugin can do. (Read on!)
To use your new plugin, make sure your ``beetsplug`` directory is in the Python
path (using ``PYTHONPATH`` or by installing in a `virtualenv`_, for example).
Then, as described above, edit your ``.beetsconfig`` to include
``plugins=myawesomeplugin`` (substituting the name of the Python module
containing your plugin).
.. _virtualenv: http://pypi.python.org/pypi/virtualenv
Add Commands to the CLI
^^^^^^^^^^^^^^^^^^^^^^^
Plugins can add new subcommands to the ``beet`` command-line interface. Define
the plugin class' ``commands()`` method to return a list of ``Subcommand``
objects. (The ``Subcommand`` class is defined in the ``beets.ui`` module.)
Here's an example plugin that adds a simple command::
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand
my_super_command = Subcommand('super', help='do something super')
def say_hi(lib, config, opts, args):
print "Hello everybody! I'm a plugin!"
my_super_command.func = say_hi
class SuperPlug(BeetsPlugin):
def commands(self):
return [my_super_command]
To make a subcommand, invoke the constructor like so: ``Subcommand(name, parser,
help, aliases)``. The ``name`` parameter is the only required one and should
just be the name of your command. ``parser`` can be an `OptionParser instance`_,
but it defaults to an empty parser (you can extend it later). ``help`` is a
description of your command, and ``aliases`` is a list of shorthand versions of
your command name.
.. _OptionParser instance: http://docs.python.org/library/optparse.html
You'll need to add a function to your command by saying ``mycommand.func =
myfunction``. This function should take the following parameters: ``lib`` (a
beets ``Library`` object), ``config`` (a `ConfigParser object`_ containing the
configuration values), and ``opts`` and ``args`` (command-line options and
arguments as returned by `OptionParser.parse_args`_).
.. _ConfigParser object: http://docs.python.org/library/configparser.html
.. _OptionParser.parse_args:
http://docs.python.org/library/optparse.html#parsing-arguments
The function should use any of the utility functions defined in ``beets.ui``.
Try running ``pydoc beets.ui`` to see what's available.
You can add command-line options to your new command using the ``parser`` member
of the ``Subcommand`` class, which is an ``OptionParser`` instance. Just use it
like you would a normal ``OptionParser`` in an independent script.
Listen for Events
^^^^^^^^^^^^^^^^^
As of beets 1.0b5, plugins can also define event handlers. Event handlers allow
you to run code whenever something happens in beets' operation. For instance, a
plugin could write a log message every time an album is successfully autotagged
or update MPD's index whenever the database is changed.
You can "listen" for events using the ``BeetsPlugin.listen`` decorator. Here's
an example::
from beets.plugins import BeetsPlugin
class SomePlugin(BeetsPlugin):
pass
@SomePlugin.listen('pluginload')
def loaded():
print 'Plugin loaded!'
Pass the name of the event in question to the ``listen`` decorator. The events
currently available are:
* *pluginload*: called after all the plugins have been loaded after the ``beet``
command starts
* *save*: called whenever the library is changed and written to disk (the
``lib`` keyword argument is the Library object that was written)
* *import*: called after a ``beet import`` command fishes (the ``lib`` keyword
argument is a Library object; ``paths`` is a list of paths (strings) that were
imported)
* *album_imported*: called with an ``Album`` object every time the ``import``
command finishes adding an album to the library
The included ``mpdupdate`` plugin provides an example use case for event listeners.
Extend the Autotagger
^^^^^^^^^^^^^^^^^^^^^
Plugins in 1.0b5 can also enhance the functionality of the autotagger. For a
comprehensive example, try looking at the ``lastid`` plugin, which is included
with beets.
A plugin can extend three parts of the autotagger's process: the track distance
function, the album distance function, and the initial MusicBrainz search. The
distance functions determine how "good" a match is at the track and album
levels; the initial search controls which candidates are presented to the
matching algorithm. Plugins implement these extensions by implementing three
methods on the plugin class:
* ``track_distance(self, item, info)``: adds a component to the distance
function (i.e., the similarity metric) for individual tracks. ``item`` is the
track to be matched (and Item object) and ``info`` is the !MusicBrainz track
entry that is proposed as a match. Should return a ``(dist, dist_max)`` pair
of floats indicating the distance.
* ``album_distance(self, items, info)``: like the above, but compares a list of
items (representing an album) to an album-level !MusicBrainz entry. Should
only consider album-level metadata (e.g., the artist name and album title) and
should not duplicate the factors considered by ``track_distance``.
* ``candidates(self, items)``: given a list of items comprised by an album to be
matched, return a list of !MusicBrainz entries for candidate albums to be
compared and matched.
When implementing these functions, it will probably be very necessary to use the
functions from the ``beets.autotag`` and ``beets.autotag.mb`` modules, both of
which have somewhat helpful docstrings.
Read Configuration Options
^^^^^^^^^^^^^^^^^^^^^^^^^^
Plugins can configure themselves using the ``.beetsconfig`` file. Define a
``configure`` method on your plugin that takes an ``OptionParser`` object as an
argument. Then use the ``beets.ui.config_val`` convenience function to access
values from the config file. Like so::
class MyPlugin(BeetsPlugin):
def configure(self, config):
number_of_goats = beets.ui.config_val(config, 'myplug', 'goats', '42')
Try looking at the ``mpdupdate`` plugin (included with beets) for an example of
real-world use of this API.

65
docs/plugins/lastid.rst Normal file
View file

@ -0,0 +1,65 @@
LastID Plugin
=============
Acoustic fingerprinting is a technique for identifying songs from the way they
"sound" rather from their existing metadata. That means that beets' autotagger
can theoretically use fingerprinting to tag files that don't have any ID3
information at all (or have completely incorrect data). The MusicBrainz project
currently uses a fingerprinting technology called PUIDs, but beets uses a
different fingerprinting algorithm provided by `Last.fm`_.
.. _Last.fm: http://last.fm/
Turning on fingerprinting can increase the accuracy of the
autotagger---especially on files with very poor metadata---but it comes at a
cost. First, it can be trickier to set up than beets itself (you need to compile
the fingerprinting code, whereas all of the beets core is written in Python).
Also, fingerprinting takes significantly more CPU and memory than ordinary
tagging---which means that imports will go substantially slower.
If you're willing to pay the performance cost for fingerprinting, read on!
Installing Dependencies
-----------------------
To use lastid, you'll need to install the `pylastfp`_ fingerprinting library,
which has a few dependencies: `fftw`_, `libsamplerate`_, and `Gstreamer for
Python`_. How you install these will depend on your operating system. Here's a
few examples:
.. _pylastfp: http://github.com/sampsyo/pylastfp
.. _fftw: http://www.fftw.org/
.. _libsamplerate: http://www.mega-nerd.com/SRC/
.. _Gstreamer for Python:
http://gstreamer.freedesktop.org/modules/gst-python.html
* On Ubuntu, just run ``apt-get install libfftw3-dev libsamplerate0-dev
python-gst0.10-dev``.
* On Arch Linux, you want
``pacman -S fftw libsamplerate gstreamer0.10-python``.
Let me know if you have a good source for installing the packages on Windows.
To decode audio formats (MP3, FLAC, etc.), you'll need the standard set of
Gstreamer plugins. For example, on Ubuntu, install the packages
``gstreamer0.10-plugins-good``, ``gstreamer0.10-plugins-bad``, and
``gstreamer0.10-plugins-ugly``.
Then, install pylastfp itself. You can do this using `pip`_, like so::
$ pip install pylastfp
.. _pip: http://pip.openplans.org/
Using
-----
Once you have all the dependencies sorted out, you can enable fingerprinting by
editing your :doc:`/reference/config`. Put ``lastid`` on your ``plugins:``
line. Your config file should contain something like this::
[beets]
plugins: lastid
With that, beets will use fingerprinting the next time you run ``beet import``.

View file

@ -0,0 +1,24 @@
MPDUpdate Plugin
================
``mpdupdate`` is a very simple plugin for beets that lets you automatically
update `MPD`_'s index whenever you change your beets library. The plugin is
included with beets as of version 1.0b5.
.. _MPD: http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki
To use it, enable it in your ``.beetsconfig`` by putting ``mpdupdate`` on your ``plugins`` line. Your ``.beetsconfig`` should look like this::
[beets]
plugins: mpdupdate
Then, you'll probably want to configure the specifics of your MPD server. You
can do that using an ``[mpdupdate]`` section in your ``.beetsconfig``, which
looks like this::
[mpdupdate]
host = localhost
port = 6600
password = seekrit
With that all in place, you'll see beets send the "update" command to your MPD server every time you change your beets library.