Library Batch Action beaTlet

A LibraryBatchAction is an action that processes each element in the library. It is meant to be fairly quick, which is why it is not persisted. If, for example, you wanted to change an attribute in the same way for each song, this would be the right way to do it.

To create your own LibraryBatchAction you need to subclass com.tagtraum.beatunes.action.standard.LibraryBatchAction and provide an implementation for the LibraryBatchAction.EachSongProcessor interface. A good way to do this is to create an inner class in your main action class. To demonstrate how this is done, check out the sample code for a PrintEachNameInLibrary-action. All it does, is to write each song name in the library to the beaTunes log. As a nice side-effect, this also shows you how to log stuff.

Sample Library Batch Action

The code is pretty self-explanatory:

# Jython

from javax.swing import Action
from org.slf4j import LoggerFactory
from com.tagtraum.beatunes.action.standard import LibraryBatchAction

# An action that allows to do something (print the name) for each song in the library.
# The corresponding menu item can be found in the 'Tools' menu.
class PrintEachNameInLibrary(LibraryBatchAction):

    # Inner class that implements the
    # com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
    # interface. Its process method is called for each song.
    class SongPrinter(LibraryBatchAction.EachSongProcessor):

        log = LoggerFactory.getLogger("PrintEachNameInLibrary.py")

        # Called once, before processing starts.
        def startProcessing(self, count):
            self.__class__.log.info("We are expecting to print %s names. Let's start!" % (count))

        # Called for each song.
        def process(self, song, index):
            # print to beaTunes log file
            self.__class__.log.info("Song: %s" % (song.getName()))

        # Called once all songs were processed.
        def finishProcessing(self):
            self.__class__.log.info("Done!")

        # Message to be shown in progress dialog.
        def getProgressDialogMessage(self, song):
            return "<html>Printing <i>%s</i> ...</html>" % (song.getName())

        # Title for progress dialog.
        def getProgressDialogTitle(self):
            return "Printing Song Names ..."

    # Unique id
    def getId(self):
        return "Jython.PrintEachNameInLibrary"

    # Is called by beaTunes as part of the lifecycle after instantiation.
    # At this point all other plugins are instantiated and registered.
    # We use this to set the menu item's (i.e. action's) name.
    def init(self):
        self.putValue(Action.NAME, "Print all Song Names")

    # We need to ask the user, whether he really wants to do this.
    # How we ask is defined here.
    def getConfirmationMessage(self):
        return "Do you really want to print all the song names in this library to the log?";

    # Factory method that creates the processor for each song.
    def createEachSongProcessor(self):
        return PrintEachNameInLibrary.SongPrinter();

// Groovy

import javax.swing.Action
import org.slf4j.LoggerFactory
import com.tagtraum.beatunes.action.standard.LibraryBatchAction
import com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
import com.tagtraum.audiokern.AudioSong

// An action that allows to do something (print the name) for each song in the library.
// The corresponding menu item can be found in the 'Tools' menu.
class PrintEachNameInLibrary extends LibraryBatchAction {

    // Inner class that implements the
    // com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
    // interface. Its process method is called for each song.
    class SongPrinter implements EachSongProcessor {

        static log = LoggerFactory.getLogger("PrintEachNameInLibrary.groovy")

        // Called once, before processing starts.
        def void startProcessing(int count) {
            log.info "We are expecting to print ${count} names. Let's start!"
        }

        // Called for each song.
        def void process(AudioSong song, int index) {
            // print to beaTunes log file
            log.info "Song: ${song.getName()}"
        }

        // Called once all songs were processed.
        def void finishProcessing() {
            log.info "Done!"
        }

        // Message to be shown in progress dialog.
        def String getProgressDialogMessage(AudioSong song) {
            "<html>Printing <i>${song.getName()}</i> ...</html>"
        }

        // Title for progress dialog.
        def String getProgressDialogTitle() {
            "Printing Song Names ..."
        }
    }

    // Unique id
    def String getId() {
        "Groovy.PrintEachNameInLibrary"
    }

    // Is called by beaTunes as part of the lifecycle after instantiation.
    // At this point all other plugins are instantiated and registered.
    // We use this to set the menu item's (i.e. action's) name.
    def void init() {
        putValue(Action.NAME, "Print all Song Names")
    }

    // We need to ask the user, whether he really wants to do this.
    // How we ask is defined here.
    def String getConfirmationMessage() {
        "Do you really want to print all the song names in this library to the log?"
    }

    // Factory method that creates the processor for each song.
    def EachSongProcessor createEachSongProcessor() {
        new SongPrinter()
    }
}

# JRuby

require 'java'

java_import javax.swing.Action
java_import org.slf4j.LoggerFactory
java_import com.tagtraum.beatunes.action.standard.LibraryBatchAction

# An action that allows to do something (print the name) for each song in the library.
# The corresponding menu item can be found in the 'Tools' menu.
class PrintEachNameInLibrary < LibraryBatchAction

    # Inner class that implements the
    # com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
    # interface. Its process method is called for each song.
    class SongPrinter
        # include is the JRuby way of implementing interfaces
        include Java::com.tagtraum.beatunes.action.standard.LibraryBatchAction::EachSongProcessor

        @@log = LoggerFactory.getLogger("PrintEachNameInLibrary.rb")

        # Called once, before processing starts.
        def startProcessing(count)
            @@log.info "We are expecting to print #{count} names. Let's start!"
        end

        # Called for each song.
        def process(song, index)
            # print to beaTunes log file
            @@log.info "Song: #{song.getName}"
        end

        # Called once all songs were processed.
        def finishProcessing
            @@log.info "Done!"
        end

        # Message to be shown in progress dialog.
        def getProgressDialogMessage(song)
            "<html>Printing <i>#{song.getName}</i> ...</html>"
        end

        # Title for progress dialog.
        def getProgressDialogTitle
            "Printing Song Names ..."
        end

    end

    # Unique id
    def getId
        "JRuby.PrintEachNameInLibrary"
    end

    # Is called by beaTunes as part of the lifecycle after instantiation.
    # At this point all other plugins are instantiated and registered.
    # We use this to set the menu item's (i.e. action's) name.
    def init
        putValue(Action::NAME, "Print all Song Names")
    end

    # We need to ask the user, whether he really wants to do this.
    # How we ask is defined here.
    def getConfirmationMessage
        "Do you really want to print all the song names in this library to the log?";
    end

    # Factory method that creates the processor for each song.
    def createEachSongProcessor
        SongPrinter.new;
    end

end

// JavaScript

                        /*
 * These type vars basically act as imports for Java classes.
 */
var Action = Java.type("javax.swing.Action");
var LoggerFactory = Java.type("org.slf4j.LoggerFactory");
var LibraryBatchAction = Java.type("com.tagtraum.beatunes.action.standard.LibraryBatchAction");
var EachSongProcessor = Java.type("com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor");
var AudioSong = Java.type("com.tagtraum.audiokern.AudioSong");

var beatlet = new LibraryBatchAction() {

    /*
     * Factory method that creates the EachSongProcessor.
     */
    createEachSongProcessor: function() {

        // Inner class that implements the
        // com.tagtraum.beatunes.action.standard.LibraryBatchAction.EachSongProcessor
        // interface. Its process method is called for each song.
        return new EachSongProcessor() {

            log: LoggerFactory.getLogger("PrintEachNameInLibrary.js"),

            /* Called once, before processing starts. */
            startProcessing: function(count) {
                this.log.info("We are expecting to print " + count + " names. Let's start!");
            },

            /* Called for each song. */
            process: function(song, index) {
                // print to beaTunes log file
                this.log.info("Song: " + song.getName());
            },

            /* Called once all songs were processed. */
            finishProcessing: function() {
                this.log.info("Done!");
            },

            /* Message to be shown in progress dialog. */
            getProgressDialogMessage: function(song) {
                return "
                        
                            Printing "+ song.getName() + " ...
                        
                        ";
            },

            /* Title for progress dialog. */
            getProgressDialogTitle: function() {
                return "Printing Song Names ...";
            }
        }
    },

    // Unique id
    getId: function() {
        return "Javascript.PrintEachNameInLibrary"
    },

    /*
     * Is called by beaTunes as part of the lifecycle after instantiation.
     * At this point all other plugins are instantiated and registered.
     * We use this to set the menu item's (i.e. action's) name.
     */
    init: function() {
        beatletSuper.putValue(Action.NAME, "Print all Song Names");
    },

    /*
     * We need to ask the user, whether he really wants to do this.
     * How we ask is defined here.
     */
    getConfirmationMessage: function() {
        return "Do you really want to print all the song names in this library to the log?";
    }
}

// Find super class of beatlet, so that we can call methods on it
// e.g. in the "init" function.
var beatletSuper = Java.super(beatlet);

// Put "beatlet" into the last line, so that it is returned to beaTunes
// when this script is eval'd.
beatlet;
                    

Curious to see more examples? Check out the playlist exporter sample code.

Other beaTlet samples:

All sample beaTlets are also on GitHub .