NAME

arename.pl - automatically rename audio files by tagging information


SYNOPSIS

arename.pl [OPTION(s)] FILE(s)...


OPTIONS AND ARGUMENTS

-d

Go into dryrun mode.

-f

Overwrite files if needed.

-h

Display a short help text.

-H

Do not make use of hooks of any sort (neither global nor local ones).

-L

List the current configuration in the actual configuration format.

-l

Read a local config file (./.arename.local). Overwrites the uselocalrc rc setting.

-q

Make the output way more quiet, when processing files.

This option conflicts with the verbose option.

-Q

Be even more quiet (this option will surpress, if a file is skipped. except for files, that are skipped because they would overwrite something).

This option implies '-q'.

-s

Read filenames from stdin after processing files given on the commandline.

-V

Display version infomation.

-v

Enable verbose output.

-c <file>

Read file instead of ~/.arenamerc.

-C <file>

Read file in after ~/.arenamerc and before ./.arename.local.

-p <prefix>

Define a prefix for destination files.

-T <template>

Define a compilation template.

-t <template>

Define a generic template.

FILE(s)...

Input files, that are subject for renaming.


DESCRIPTION

arename.pl is a tool that is able to rename audio files by looking at a file's tagging information, from which it will assemble a consistent destination file name. The format of that filename is configurable for the user by the use of template strings.

arename.pl currently supports three widely used audio formats, namely MPEG Layer3, ogg vorbis and flac. The format, that arename.pl will assume for each input file is determined by the file's filename-extension (.mp3 vs. .ogg vs. .flac). The extension check is case-insensitive.

By default, arename.pl will refuse to overwrite destination files, if the file in question already exists. You can force overwriting by supplying the -f option.


FILES

Configuration files

arename.pl uses up to two configuration files. As for most programs, the script will try to read a configuration file, that is located in the user's home directory. In addition to that, it will try to load local configuration files, if it finds appropriately named files in the current directory.

~/.arenamerc

per-user global configuration file.

./.arename.local

per-directory local configuration file.

File format

The format of the aforementioned files is pretty simple. It is parsed line by line. Empty lines, lines only containing whitespace and lines, whose first non whitespace character is a hash character (#) are ignored.

Each line consists of one or two parts. If there are two parts, they are separated by whitespace. The first part of the line will be used as the identifier of a setting (eg. verbose). The second part (read: the rest of the line) is used as the value of the setting. (No quoting, or whatsoever is required.)

If the value part start with a backslash, that backslash is left out of the value. That makes it possible to define templates with leading whitespace.

If a line consists of only one part, that means the setting is switched on.

If a line contains only a string within square brackets, that string is the start of a section. Section names are matches for starts of file names. That means, the following settings are will only applied for input file names that start with the same string as the section name. Where file name means the string, handed over to arename.pl. The string ~/ at the beginning of a section name is expanded to the user's home directory.

You may start as many sections as you would like.

A section named /foo/bar/ supersedes a section named /foo/ for a file named /foo/bar/baz.ogg. So, the longest match wins.

Configuration file example

  # switch on verbosity
  verbose
  # the author is crazy! use a sane template by default. :-)
  template &artist - &album (&year) - &tracknumber. &tracktitle
  # force files from /foo/bar/ to stay below that directory
  [/foo/bar/]
  prefix /foo/bar

Hook definition files

~/.arename.hooks

Defines global hooks, that are in effect in every directory if the usehooks option is set to true.

./.arename.hooks.local

This allows you to define special hooks, that will only be applied for processes that run in the directory the local file is found (and if the uselocalhooks option is set to true).

For details about hooks in arename.pl, see HOOKS below.


SETTINGS

The following settings are supported in all configuration files:

canonicalize

If set, a given file name will be transformed to its cleaned up absolute path. You may want to set this, if you are using sections in the configuration. If you do not use sections, all this will give you is a performance penalty. (default value: false)

comp_template

Defines a template to use with files that provide a compilation tag (for 'various artist' CDs, for example). This setting can still be overwritten by the -T command line option. (default value: va/&album/&tracknumber - &artist - &tracktitle)

default_*

default_artist, default_album, default_compilation, default_genre, default_tracknumber, default_tracktitle, default_year

Defines a default value, for the given tag in files, that lack this information. (default value: undefined)

hookerrfatal

If this is set to false, arename.pl will continue execution even if reading, parsing or compiling a hooks file failed. (default value: false)

prefix

Defines a prefix for destination files. This setting can still be overwritten by the -p command line option. (default value: .)

quiet

Switches on quietness by default. (default value: off)

quiet_skip

Be quiet about skips by default. This implicitly sets 'quiet'. (default value: off)

sepreplace

Tagging information strings may contain slashes, which is a pretty bad idea on most filesystems. Therefore, you can define a string, that replaces slashes with the value of this setting. (default value: _)

template

Defines a template to use with files that do not provide a compilation tag (or where the compilation tag and the artist tag are exactly the same). This setting can still be overwritten by the -T command line option. (default value: &artist[1]/&artist/&album/&tracknumber - &tracktitle)

tnpad

This defines the width, to which the tracknumber field is padded with zeros on the left. (default value: 2)

usehooks

If set to true use hooks defined in ~/.arename.hooks. (default value: true)

uselocalhooks

If set to true use hooks defined in ./.arename.hooks.local. (default value: false)

uselocalrc

If set to true, read a local configuration file (./.arename.local), if it exists. (default value: false)

verbose

Switches on verbosity by default. (default value: off)

User defined variables

You can use the set command in arenamerc files. This way the user can define his own variables. The namespace is seperate from arename.pl's normal settings. (That means, you cannot, for example, overwrite the internal template variable with this command.)

set varname = value

There may be an arbitrary amount of whitespace around the equal sign (including no whitespace at all). If you want to have a value that starts in a whitespace character, you may start the value with a backslash character (just like with the template settings, a leading backslash is always ignored).

User defined variables are useful to make hooks configurable (see HOOKS below).


TEMPLATE FORMAT

arename.pl's templates are quite simple, yet powerful.

At simplest, a template is just a fixed character string. However, that would not be exactly useful. So, the script is able to expand certain expressions with information gathered from the file's tagging information.

The expressions can have two slightly different forms:

&identifier

The simple form.

&identifier[length]

The ``complex'' form. The length argument in square brackets defines the maximum length, to which the expression should be expanded.

That means, if the Artist of a file reveals to be 'Frank Zappa', then using '&artist[1]' will expand to 'F'.

Available expression identifiers

The data, that is expanded is derived from tagging information in the audio files. For .ogg and .flac files, the tag checking arename.pl does is case insensitive and the first matching tag will be used.

album

Guess.

artist

Guess again.

compilation

For .ogg and .flac this is filled with information found in the 'albumartist' tag. For .mp3 this is filled with information from the id3v2 TPE2 frame. If the mp3 file only provides a id3v1 tag, this is not supported.

genre

The genre or content type of the audio file.

tracknumber

The number of the position of the track on the disc. Obviously. However, this can be in the form of '12' or '12/23'. In the second form, only the part left of the slash is used. The tracknumber is a little special, as you can define to what width it should be padded with zeros on the left (see tnpad setting in SETTINGS).

tracktitle

Well...

year

Year (id3v1), TYER (id3v2) or DATE tag (.ogg/.flac).


HOOKS

Before we start, a word of warning: Hooks can solve a lot of problems. That amount of flexibility comes with its price. All data passed to hook functions are references to the actual data in the script (except for the namespace argument, which is a copy). If you write hooks carelessly, arename.pl will get back at you! HOOKS ARE A BIG HAMMER, THAT CAN CRUSH PROBLEMS AS WELL AS LIMBS!

You have been warned!

Discussion

The reason for implementing hooks was to have a simple way of post processing tags, filenames etc. without having to invent own magic in the configuration files, when Perl has regular expressions on steriods anyway. Hooks can do more then pure pre and post processing, because they are called in numerous places and give broad access to the script's data structures. Still, post processing is probably the most useful feature they implement.

Hooks are just Perl subroutines, which are defined in one of two files (see FILES). They are run at certain events during the execution of arename.pl. The contents of the argument list for each hook depends on what hook is called (see the list of hook events below). However, the first argument (argument zero aka. $_[0]) to all hooks is the namespace, the hook is called in.

The global hooks file is read before the local one, which means, that this local file may overwrite and extend the definitions from the global file, as much as Perl permits. This also means, that hooks from the local file are run after the ones from the global file (unless you are using your own method of registering hooks; but if you do so, you know what you are doing anyway).

Subroutines must be registered to arename.pl, to be known as hooks. Once registered, a subroutine can be removed from the known hooks, if requested (see 'Utility subroutines' below).

The keys in various data hashes passed to the hooks can be one of the following: album, artist, compilation, genre, tracknumber, tracktitle, year.

Hooks can also use the data from user defined variables, by using their Perl interface (user_get() and user_set()):

  # Assume, the user set the myvar-variable to "bar"
  my $foo = user_get('myvar');    # $foo is now "bar"
  user_set('foo', "bar, baz");
  my $foo = user_get('myvar');    # $foo is now "bar, baz"

The currently processed file name can be accessed via two subroutines: get_file() and set_file(). That way, you could even change the file name of the processed file, while arename.pl works on it (which you really should only do, if you know what you are doing).

Utility subroutines

There are two subroutines, that are used to tell arename.pl about subroutines, you defined that shall become hooks.

register_hook(event, coderef)

Registers a code reference (read: your subroutine) for the given event. Example: register_hook('startup', \&custom_banner);

remove_hook(event, coderef)

Removes all entries of the code reference for the given event. Example: remove_hook('startup', \&custom_banner);

If the coderef was added more than once, all entries are removed.

List of hook events

Hooks in the main loop

These hooks are called at the highest level of the script.

canonicalize

This is called in the middle of the file name canonicalization process (but only it is enabled via the canonicalize setting).

Get the current file name via get_file(). The canonicalized file name is handed to you via the hook's arguments. The value from this argument will be assigned to the processed filename after the execution of this hook.

Arguments: 1: canonicalized file name

next_file_early

Called at the start of the main loop before any file checks are done.

Arguments:

next_file_late

Called in the main loop after the file checks are done.

Arguments:

file_done

Called in the main loop after the file has been processed.

Arguments:

filetype_unknown

Called in the main loop after the file was tried to be processed but the file type (the extension, specifically) was unknown.

Arguments:

Hooks in the renaming procedure

When all data has been gathered, arename.pl will go on to actually rename the files to their new destination name (which will be generated in the process, see Hooks when expanding the template below).

pre_apply_defaults

This is the first action to be taken in the renaming process. It is called even before the default values are applied.

Arguments: 1: data hash, 2: file extension

pre_template

Called before template expansions have been done.

Arguments: 1: data hash, 2: file extension

post_template

Called after the template has been expanded and the new file name has been completely generated (including the destination directory prefix).

Arguments: 1: data hash, 2: file extension 4: the generated new filename (including directory prefix and file extension)

post_ensure_dir

The destnation directory for the new file name may contain sub directories, which currently do not exist. This hook is called after it is ensured, every directory portion exists.

Arguments: 1: data hash, 2: file extension 4: the generated new filename (including directory prefix and file extension)

post_rename

This is the final hook in the actual renaming process. The file has been renamed at this point.

Arguments: 1: data hash, 2: file extension 4: the generated new filename (including directory prefix and file extension)

Hooks when expanding the template

These hooks are called when the template string is filled with the data from tags in the audio files. All file type specific actions will have been taken care of already. That makes these hooks probably most useful for post processing tags, the template and file names.

pre_expand_template

Called before any expansions are done.

Arguments: 1: the template string, 2: the data hash

expand_template_next_tag

This hook is triggered when the next identifier in the template string is processed. At this point it is already verified, that there is an according tag in the data hash to fill in the identifier's space.

Arguments: 1: the template string, 2: the tag's name 3: the value of the length modifier in the template (zero, if unspecified) 4: the data hash

expand_template_postprocess_tag

This hooks is triggered after all internal processing of the replacement token is done (directory seperators are replaced; tracknumbers are padded up).

Arguments: 1: the template string, 2: the text token, that will replace the identifier in the template, 3: the tag's name 4: the value of the length modifier, 5: the data hash

post_expand_template

Called after all expansions have been done, right before the the resulting string is returned.

Arguments: 1: the template string, 2: the data hash

Hooks when gathering information

These hooks are triggered while the tag information is extracted from the audio files arename.pl is processing. Due to the differing nature of the the involved backends, these are slightly different from file type to file type.

Specifically, the tag for .ogg and .flac files are read one after another (the tags in these files are pretty much the same, hence they are processed exactly the same), whereas tags in .mp3 files are read all at the same time.

pre_process_flac

.flac only!

Called before a flac file is processed.

Arguments:

post_process_flac

.flac only!

Called after a flac file is processed.

Arguments:

pre_process_ogg

.ogg only!

Called before an ogg file is processed.

Arguments:

post_process_ogg

.ogg only!

Called after an ogg file is processed.

Arguments:

pre_handle_vorbistag

.ogg and .flac only!

Triggered before any processing of a certain tag. It is not ensured that the tag is even among the supported tags at this point.

Arguments: 1: tag name, 2: tag value, 3: data hash

pre_handle_vorbistag

.ogg and .flac only!

Triggered after a certain tag was processed.

Arguments: 1: tag name, 2: tag value, 3: the internal name for the tag (also used as the key in the data hash), 4: data hash

pre_process_mp3

.mp3 only!

Called before an mp3 file is processed.

Arguments:

post_process_mp3

.mp3 only!

Called after an mp3 file is processed.

Arguments:

pre_handle_mp3tag

.mp3 only!

Called before data from the mp3 object is copied to the data hash.

Arguments: 1: the mp3 object, 2: data hash

post_handle_mp3tag

.mp3 only!

Called after data from the mp3 object has been copied to the data hash.

Arguments: 1: the mp3 object, 2: data hash

Miscellaneous hooks

apply_defaults

This is triggered before values from the default_* settings are applied to missing values in the audio file. This hook is only run if the default value for a tag will be used!

Arguments: 1: data hash, 2: defaults hash, 3: current key

pre_method

This hook is called after a method for a file type is choosen but before the method was executed.

Arguments: 1: method name

post_method

Called after a method for a file type was executed.

Arguments: 1: method name

startup

Called directly after all the module initialisation is done, at the very start of the script. Configuration files will have been read, as well as hook files (obviously) and command line options will have been handled at this point already.

This hook may be useful for postprocessing the configuration as well as for debugging.

Arguments: 1: program name, 2: its version, 3: configuration hash, 4: hash of extensions, that point the the according method for the file type 5: array of supported tags, 6: the program's argument list

normal_quit

Called at the end of the script. This is reached if nothing fatal happened.

Arguments: 1: the program's argument list

Example

This is a very simple example for a hook file, that prints a custom banner and replaces all whitespace in the expanded template with underscores:

  sub my_banner { oprint "Hello World.\n"; }
  sub replace_spaces_by_underscore {
      my ($templateref, $datref) = @_;
      $$templateref =~ s/\s+/_/g;
  }
  register_hook('startup', \&my_banner);
  register_hook('post_expand_template',
      \&replace_spaces_by_underscore);

Further examples can be found in the arename.hook file of the distribution.


SEE ALSO

the Ogg::Vorbis::Header manpage, the Audio::FLAC::Header manpage and the MP3::Tag manpage.


AUTHOR

Frank Terbeck <ft@bewatermyfriend.org>,

Please report bugs.


LICENCE

 Copyright 2007, 2008
 Frank Terbeck <ft@bewatermyfriend.org>, All rights reserved.
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
   1. Redistributions of source code must retain the above
      copyright notice, this list of conditions and the following
      disclaimer.
   2. Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials
      provided with the distribution.
  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS OF THE
  PROJECT BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.