Git Product home page Git Product logo

drop2beets's Introduction

drop2beets

A Beets plug-in that imports singles as soon as they are dropped in a folder.

You can provide a function to set meta-data or custom attributes depending on the sub-folder in which the file has been dropped. The examples folder contains some examples of on_item functions you may adapt to your needs.

We use Beets' auto-tagger in quiet mode, and inotify to detect dropped files.

Get started

You'll need Python3 and an existing Beets library. Run:

pip install drop2beets

Enable and configure the plug-in by running beet config -e and set at least the path to the "dropbox" folder.

plugins: drop2beets
drop2beets:
    dropbox_path: ~/beets-dropbox

We advise you configure Beets to always move files out of the Dropbox, and set quiet_fallback:

import:
    move: yes
    copy: no
    quiet_fallback: asis

quiet_fallback tells Beets what to do when the auto-tagger is not sure about the song's identifiaction. Set it to skip to abort the importation in case of ambiguity, or asis to import using tags as they are in the incoming file. This will avoid surprises in case of ambiguous matches, because this script invokes Beet's auto-tagger in quiet mode (as beet import -q) after your custom function.

This function is on_item. It is written in Python, and lets you set some tags depending of which sub-folder the file is dropped in. If you want one, define it in the configuration from this template:

drop2beets:
    on_item: |
        def on_item(item, path):
            """
            Parameters:
                item: the beets Item that we're about to import
                path: its sub-folders path in our dropbox ; if the items has been dropped at the root, then it's empty.
            Returns:
                A dict of custom attributes (according to path, maybe) ; return None if you don't want to import the file right now.
            """
            return {}

Now you're ready to test by calling beet dropbox on the command line and dropping a few files in the folder. Hit Ctrl+C to close the script.

For a longer-term installation, configure a log file path

drop2beets:
    log_path: ~/drop2beets/log.log

Linux users can install this as a user-lever systemd service by running beet install_dropbox (in a shell where the virtual environment is activated). Note that you'll have to restart the service when you update the on_item function.

Examples wanted !

I'd be happy to include your own variations of this script or the on_item function in the examples folder, feel free to post them in Issues or Pull Requests.

drop2beets's People

Contributors

martinkirch avatar tsuereth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

tsuereth

drop2beets's Issues

AttributeError: 'ImportTask' object has no attribute 'item' (in on_import_task_created)

I noticed this behavior when using drop2beets with the beets importer's "group_album" setting enabled.

Repro steps:

  1. Set up beets with the drop2beets plugin + the import option "group_album: yes", and start the drop2beets watcher.
    1. docker run --rm -it --entrypoint bash --name drop2beets python
    2. pip install beets drop2beets
    3. mkdir -p ~/.config/beets/ && echo -e "plugins: drop2beets\n\nimport:\n group_albums: yes\n\ndrop2beets:\n dropbox_path: /dropbox" > ~/.config/beets/config.yaml
    4. mkdir /dropbox
    5. beet dropbox
  2. Add any audio file to the watch path.
    1. Example file: https://github.com/beetbox/beets/blob/master/test/rsrc/whitenoise.mp3
    2. (From outside the watcher process/shell) docker cp whitenoise.mp3 drop2beets:/dropbox/
  3. Wait a moment, and the dropbox watcher will error and exit.

Abridged traceback:

  File "/usr/local/lib/python3.12/site-packages/beetsplug/drop2beets.py", line 112, in on_import_task_created
    path = str(task.item.path, 'utf-8', 'ignore')
               ^^^^^^^^^
AttributeError: 'ImportTask' object has no attribute 'item'. Did you mean: 'items'?

Evidently, some ImportTasks just don't have an item, by design. Ref. https://github.com/beetbox/beets/blob/master/beets/importer.py

class SentinelImportTask(ImportTask):
    """A sentinel task marks the progress of an import and does not
    import any items itself.

I don't think that these item-less tasks are relevant to drop2beets - since there's no file path to filter or handle - so the plugin can happily ignore the task and move along. ๐Ÿ˜Ž Pull request incoming!

Inotify error -1

I'm trying to use beets as auto-tagger for music downloaded from different sources. Each source put the files on one subfolder, and i'm hopping to use this plugin for automatic clasification.
My problem is, when i try to launch "beet dropbox", a exception is raised. It looks like is produced by inotify. My environment is a docker container, which i suppose is the mainly problem, but i'm not really sure. Here is the output

beet dropbox
Traceback (most recent call last):
File "/usr/bin/beet", line 8, in
sys.exit(main())
File "/usr/lib/python3.10/site-packages/beets/ui/init.py", line 1285, in main
_raw_main(args)
File "/usr/lib/python3.10/site-packages/beets/ui/init.py", line 1272, in _raw_main
subcommand.func(lib, suboptions, subargs)
File "/config/drop2beets/beetsplug/drop2beets.py", line 93, in _main
i = InotifyTree(self.dropbox_path)
File "/config/.local/lib/python3.10/site-packages/inotify/adapters.py", line 340, in init
self.__load_tree(path)
File "/config/.local/lib/python3.10/site-packages/inotify/adapters.py", line 362, in __load_tree
self._i.add_watch(path, self._mask)
File "/config/.local/lib/python3.10/site-packages/inotify/adapters.py", line 95, in add_watch
wd = inotify.calls.inotify_add_watch(self.__inotify_fd, path_bytes, mask)
File "/config/.local/lib/python3.10/site-packages/inotify/calls.py", line 34, in _check_nonnegative
raise InotifyError("Call failed (should not be -1): (%d)" %
inotify.calls.InotifyError: Call failed (should not be -1): (-1) ERRNO=(0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.