This is Info file pm.info, produced by Makeinfo version 1.68 from the
input file bigpm.texi.


File: pm.info,  Node: Apache/Language/Constants,  Next: Apache/Language/DBI,  Prev: Apache/Language,  Up: Module List

Apache::Language constants for use by LanguageHandlers
******************************************************

NAME
====

   Apache::Language::Constants - Apache::Language constants for use by
LanguageHandlers

SYNOPSIS
========

     use Apache::Language::Constants;

DESCRIPTION
===========

   These are constants LanguageHandlers can use to return status
information to Apache::Language.  The constants and their respective
signification are as follow:

L_OK
     Return with this value whenever something correctly ends

L_ERROR
     Return with this value whenever something bad has happened.  By bad,
     I mean something that will prevent you to complete the required task
     and that some form of error should be generated in the logs.

L_DECLINED
     return with this value in the initialize routine to indicate you are
     not interested in being called to answer queries for that package.
     How you decide this is up to you.

   Remember to return undef when a search retrieves nothing and all will
be ok.

SEE ALSO
========

   perl(1), *Note Apache: Apache,(3), *Note Apache/Language:
Apache/Language,(3).

SUPPORT
=======

   Please send any questions or comments to the Apache modperl mailing
list <modperl@apache.org> or to me at <gozer@ectoplasm.dyndns.com>

AUTHOR
======

   Philippe M. Chiasson <gozer@ectoplasm.dyndns.com>

COPYRIGHT
=========

   Copyright (c) 1999 Philippe M. Chiasson. All rights reserved. This
program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.


File: pm.info,  Node: Apache/Language/DBI,  Next: Apache/Language/PlainFile,  Prev: Apache/Language/Constants,  Up: Module List

DBI interface for Apache::Language
**********************************

NAME
====

   Apache::Language::DBI - DBI interface for Apache::Language

SYNOPSIS
========

     <Location /under/language/control/>
     PerlSetVar Language::DBI::Datasource  DBI:Pg:dbname=database;host=database.host
     PerlSetVar Language::DBI::Username webserver
     PerlSetVar Language::DBI::Password unguessable
     PerlSetVar Language::DBI::TableName language [default]
     Language::DBI::TableKey		key 	[column for the key]
     Language::DBI::TableLang		lang	[column for the lang]
     Language::DBI::TableValue 	value [column for the value]
     LanguageHandler Apache::Language::DBI
     </Location>

DESCRIPTION
===========

   This LanguageHandler implements a per-location DBI dictionnary.  It
looks-up a given table for a matching language/key pair and returns the
best possible match.

   The configurable directives are pretty self-explanatory.

TODO
====

   Some sort of caching could be done.

SEE ALSO
========

   perl(1), *Note Apache: Apache,(3), *Note Apache/Language:
Apache/Language,(3) *Note Apache/Language/Constants:
Apache/Language/Constants,(3), and all `Apache::Language::*' in this node.

SUPPORT
=======

   Please send any questions or comments to the Apache modperl mailing
list <modperl@apache.org> or to me at <gozer@ectoplasm.dyndns.com>

NOTES
=====

   This code was made possible by :

   * Doug MacEachern <dougm@pobox.com>  Creator of mod_perl.  That should
     mean enough.

   * Andreas Koenig <koenig@kulturbox.de> The one I got the idea from in
     the first place.

   * The mod_perl mailing-list at <modperl@apache.org> for all your
     mod_perl related problems.

AUTHOR
======

   Philippe M. Chiasson <gozer@ectoplasm.dyndns.com>

COPYRIGHT
=========

   Copyright (c) 1999 Philippe M. Chiasson. All rights reserved. This
program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.


File: pm.info,  Node: Apache/Language/PlainFile,  Next: Apache/Language/SW,  Prev: Apache/Language/DBI,  Up: Module List

Default LanguageHandler under Apache::Language
**********************************************

NAME
====

   Apache::Language::PlainFile - Default LanguageHandler under
Apache::Language

SYNOPSIS
========

     Since it's the default handler, it never needs to be activated.

DESCRIPTION
===========

   This is the default LanguageHandler under Apache::Language.  It
searches language definitions for a specific script/module in a file with
a corresponding name.  For a script, it's the scriptname with a .dic
added.  For a module, simply replace the .pm with a .dic

   That file must reside in the same directory as the script/module it
describes, and be readable by the web-server process.  The format of that
file is as follows:

   language-tag:Key

   Content for 'language' version of 'Key'

   language-tag:Key

   [...]

   The only really important thing is to make sure that entries are
separated with completely blank lines.

TODO
====

   Nothing for now.

SEE ALSO
========

   perl(1), *Note Apache: Apache,(3), *Note Apache/Language:
Apache/Language,(3) *Note Apache/Language/Constants:
Apache/Language/Constants,(3), and all `Apache::Language::*' in this node.

SUPPORT
=======

   Please send any questions or comments to the Apache modperl mailing
list <modperl@apache.org> or to me at <gozer@ectoplasm.dyndns.com>

NOTES
=====

   This code was made possible by :

   * Doug MacEachern <dougm@pobox.com>  Creator of mod_perl.  That should
     mean enough.

   * Andreas Koenig <koenig@kulturbox.de> The one I got the idea from in
     the first place.

   * The mod_perl mailing-list at <modperl@apache.org> for all your
     mod_perl related problems.

AUTHOR
======

   Philippe M. Chiasson <gozer@ectoplasm.dyndns.com>

COPYRIGHT
=========

   Copyright (c) 1999 Philippe M. Chiasson. All rights reserved. This
program is free software; you can redistribute it and/or modify it under
the same terms as Perl itself.


File: pm.info,  Node: Apache/Language/SW,  Next: Apache/Layer,  Prev: Apache/Language/PlainFile,  Up: Module List

LanguageHandler for SmartWorker Applications
********************************************

NAME
====

   Apache::Language::SW - LanguageHandler for SmartWorker Applications

SYNOPSIS
========

     sub new
     {
        my $classname = shift;
     	   my $self = $classname->SUPER::new(@_);
        $self->{Language} = new Apache::Language($self);
        [...]
     }
     
        [...]
        -text => $self->{Language}{"keyName1"},
        [...]
     
        #outside a FormPanel
        $Panel->addElement(x,y,$self->{Language}->getLanguagePicker());
     
        #inside a FormPanel
        $Panel->addElement(x,y,$self->{Language}->getLanguagePicker("formPanel1));
        [...]

DESCRIPTION
===========

   This is the new way to handle Language in SW::Applications.  The
interface is a tied hash, so you can use the object returned by
Apache::Language like any other hash reference.

   There are also a few function calls you can make on it, like the
getLanguagePicker() sub that returns a Language picker panel ready to
insert in your application.

   The only restriction with this module is that it uses the 'Lang' key to
find wanted languages.  So it sets it in the Session/Data stuff.  So don't
do this:

     $self->{Lang} = "I love perl";
     or
     $self->setSessionValue("Lang","I love perl");
     ok ?
     
     
     But you can look at it if you want to know what language are requested by the user,
     but I advise against it.

METHODS
=======

     getLanguagePicker - Returns a formpanel with a correct language picker for the current user.
     
     Arguments : if already in form context, call it with the name of the formpanel you are adding it to.

AUTHOR
======

   Philippe M. Chiasson HBE	gozer@hbe.ca Sept  9/99

REVISION HISTORY
================

     $Log$

SEE ALSO
========

   perl(1).

   Apache::Language(3).

   Apache::Language::*(3).


File: pm.info,  Node: Apache/Layer,  Next: Apache/Leak,  Prev: Apache/Language/SW,  Up: Module List

Layer content tree over one or more others.
*******************************************

NAME
====

   Apache::Layer - Layer content tree over one or more others.

SYNOPSIS
========

     #httpd.conf
     PerlTransHandler Apache::Layer

     # anywhere you can configure a location
     <Location /project/images>
         PerlSetVar apache_layer_location /project/images
         PerlSetVar apache_layer_path     /dir1/root;/dir2/root
     </Location>

DESCRIPTION
===========

   This module is designed to allow multiple content trees to be layered
on top of each other within the Apache server.

   I developed this module because we produce lots of web sites where a
high proportion of the site content is common.  But where specific pages /
images are tailored to the specific project.  This module allows us to
layer a sparse directory tree on top of the main complete tree without
requiring redirects.

   The essence is that it will cause Apache to deliver content from a
series of directories in turn.

   In some ways Apache::Layer is similar to Apache::Stage however it does
not require redirects.

COMMON PROBLEMS
===============

   Apache::Layer is relatively simple.  The most common problem is not
setting the apache_layer_location parameter correctly.  As a rule this
parameter should ALWAYS match the parameter within the location i.e.
<Location /parameter>.

AUTHOR
======

   Simon Matthews <sam@peritas.com>

REVISION
========

   $Revision: 1.7 $

COPYRIGHT
=========

   Copyright (C) 1998 Simon Matthews.  All Rights Reserved.

   This module is free software; you can distribute it and/or modify it
under the same terms as Perl itself.

SEE ALSO
========

   Apache::Stage


File: pm.info,  Node: Apache/Leak,  Next: Apache/Log,  Prev: Apache/Layer,  Up: Module List

Module for tracking memory leaks in mod_perl code
*************************************************

NAME
====

   Apache::Leak - Module for tracking memory leaks in mod_perl code

SYNOPSIS
========

     use Apache::Leak;

     leak_test {
     	my $obj = Foo->new;
     	$obj->thingy;
     };
     #now look in error_log for results

DESCRIPTION
===========

   "Under Construction."

SEE ALSO
========

   Devel::Leak

AUTHOR
======

   Doug MacEachern Leak.xs derived from Nick Ing-Simmons' Devel::Leak


File: pm.info,  Node: Apache/Log,  Next: Apache/LogFile,  Prev: Apache/Leak,  Up: Module List

Interface to Apache logging
***************************

NAME
====

   Apache::Log - Interface to Apache logging

SYNOPSIS
========

     use Apache::Log ();
     my $rlog = $r->log;
     $rlog->debug("You only see this if `LogLevel' is set to `debug'");

     my $slog = $r->server->log;

DESCRIPTION
===========

   The Apache::Log module provides an interface to Apache's *ap_log_error*
and *ap_log_rerror* routines.

emerg
alert
crit
error
warn
notice
info
debug
AUTHOR
======

   Doug MacEachern

SEE ALSO
========

   mod_perl(3), Apache(3).


File: pm.info,  Node: Apache/LogFile,  Next: Apache/MP3,  Prev: Apache/Log,  Up: Module List

Interface to Apache's logging routines
**************************************

NAME
====

   Apache::LogFile - Interface to Apache's logging routines

SYNOPSIS
========

     #in httpd.conf
     PerlModule Apache::LogFile
     PerlLogFile |perl/mylogger.pl My::Logger

     #in a Perl script
     print My::Logger "a message to the Log"

DESCRIPTION
===========

   The *PerlLogFile* directive can be used to hook a Perl filehandle to a
piped logger or to a file open for appending.  If the first character of
the filename is a |, the file handle is opened as a pipe to the given
program.  The file or program can be relative to the *ServerRoot*.

   The method interface was written before mod_perl directive handlers were
introduced, but it still works so the documentation remains below:

   The new method should be called by a server startup script or module.

   The last argument to new is optional, it is simply a name that can be
used to retrive the filehandle via the handle method.

     #in a startup file
     use Apache::LogFile ();
     Apache::LogFile->new("|perl/mylogger.pl", "MyLogger");

     #in a request-time file
     use Apache::LogFile ();
     my $fh = Apache::LogFile->handle("MyLogger");
     print $fh "a message to the log";

   If this argument is not present, the filename will be used the handle
key, which can also be retrived via the handle method.  The new method
will return a reference to the filehandle if you wish to store it
elsewhere, e.g.:

     $MyLog::Pipe = Apache::LogFile->new("|perl/mylogger.pl");

     $MyLog::Append = Apache::LogFile->new("logs/my_log");

AUTHOR
======

   Doug MacEachern

SEE ALSO
========

   Apache(3), mod_perl(3)


File: pm.info,  Node: Apache/MP3,  Next: Apache/MP3/Playlist,  Prev: Apache/LogFile,  Up: Module List

Generate streamable directories of MP3 files
********************************************

NAME
====

   Apache::MP3 - Generate streamable directories of MP3 files

SYNOPSIS
========

     # httpd.conf or srm.conf
     AddType audio/mpeg     mp3 MP3
     AddType audio/playlist m3u M3U

     # httpd.conf or access.conf
     <Location /songs>
       SetHandler perl-script
       PerlHandler Apache::MP3
     </Location>

     # Or use the Apache::MP3::Sorted subclass to get sortable directory listings
      <Location /songs>
      SetHandler perl-script
      PerlHandler Apache::MP3::Sorted
      </Location>

     # Or use the Apache::MP3::Playlist subclass to get persistent playlists
      <Location /songs>
      SetHandler perl-script
     PerlHandler Apache::MP3::Playlist
      </Location>

   A *demo version* can be browsed at http://www.modperl.com/Songs/.

DESCRIPTION
===========

   This module makes it possible to browse a directory hierarchy
containing MP3 files, sort them on various fields, download them, stream
them to an MP3 decoder like WinAmp, and construct playlists.  The display
is configurable and subclassable.

   NOTE: This version of Apache::MP3 is substantially different from the
pre-2.0 version described in The Perl Journal.  Specifically, the format
to use for HREF links has changed.  See *Linking* for details.

Installation
------------

   This section describes the installation process.

  1. Prequisites This module requires mod_perl and MP3::Info, both of
     which are available on CPAN.

  2. Configure MIME types Apache must be configured to recognize the mp3
     and MP3 extensions as MIME type audio/mpeg.  Add the following to
     httpd.conf or srm.conf:

          AddType audio/mpeg mp3 MP3
          AddType audio/playlist m3u M3U

  3. Install icons and stylesheet This module uses a set of icons and a
     cascading stylesheet to generate its song listings.  By default, the
     module expects to find them at the url /apache_mp3.  Create a
     directory named apache_mp3 in your document root, and copy into it
     the contents of the `apache_mp3' directory from the Apache-MP3
     distribution.

     You may change the location of this directory by setting the BaseDir
     configuration variable.  See the Customizing section for more details.

  4. Set Apache::MP3 to be the handler for the MP3 directory In httpd.conf
     or access.conf, create a <Location> or <Directory> section, and make
     Apache::MP3 the handler for this directory.  This example assumes you
     are using the URL /Songs as the directory where you will be storing
     song files:

          <Location /Songs>
            SetHandler perl-script
            PerlHandler Apache::MP3
          </Location>

     If you would prefer an MP3 file listing that allows the user to sort
     it in various ways, set the handler to use the Apache::MP3::Sorted
     subclass instead.  A further elaboration is Apache::MP3::Playlist,
     which uses cookies to manage a persistent playlist for the user.

  5. Load MP3::Info in the Perl Startup file (optional) For the purposes
     of faster startup and memory efficiency, you may load the MP3::Info
     module at server startup time.  If you have a mod_perl "startup"
     file, enter these lines:

          use MP3::Info;
          use Apache::MP3;

  6. Set up MP3 directory Create a directory in the web server document
     tree that will contain the MP3 files to be served.  The module
     recognizes and handles subdirectories appropriately.  I suggest
     organizing directories hierarchically by artist and/or album name.

     If you place a file named "cover.jpg" in any of the directories, that
     image will be displayed at the top of the directory listing.  You can
     use this to display cover art.

     If you place a list of .mp3 file names in a file with the .m3u
     extension, it will be treated as a playlist and displayed to the user
     with a distinctive icon.  Selecting the playlist icon will download
     the playlist and stream its contents.  The playlist must contain
     relative file names, but may refer to subdirectories, as in this
     example:

          # file: folk_favorites.m3u
          Never_a_Moment_s_Thought_v2.mp3
          Peter Paul & Mary - Leaving On A Jet Plane.mp3
          Simon and Garfunkel/Simon And Garfunkel - April Come She Will.mp3

  7. Set up an information cache directory (optional) In order to generate
     its MP3 listing, Apache::MP3 must open each sound file, extract its
     header information, and close it.  This is time consuming,
     particularly when recursively generating playlists across multiple
     directories.  To speed up this process, Apache::MP3 has the ability
     cache MP3 file information in a separate directory area.

     To configure this, choose a directory that the Web server has write
     access for, such as /usr/tmp.  Then add a configuration variable like
     the following to the <Location> directive:

          PerlSetVar  CacheDir       /usr/tmp/mp3_cache

     If the designated directory does not exist, Apache::MP3 will attempt
     to create it, limited of course by the Web server's privileges.  You
     may need to create the mp3_cache directory yourself if /usr/tmp is not
     world writable.

        Open up the MP3 URL in your favorite browser.  You should be able
to see directory listings, and download and stream your songs.  If things
don't seem to be working, checking the server error log for messages.

CUSTOMIZING
===========

   Apache::MP3 can be customized in three ways: (1) by changing
per-directory variables; (2) changing settings in the Apache::MP3
cascading stylesheet; and (3) subclassing Apache::MP3 or
Apache::MP3::Sorted.

Per-directory configuration variables
-------------------------------------

   Per-directory variables are set by PerlSetVar directives in the
Apache::MP3 <Location> or <Directory> section.  For example, to change the
icon displayed next to subdirectories of MP3s, you would use PerlSetVar to
change the DirectoryIcon variable:

     PerlSetVar DirectoryIcon big_cd.gif

   This following table summarizes the configuration variables.  A more
detailed explanation of each follows in the subsequent sections.

   Table 1: Configuration Variables

     Name                  Value	        Default
     ----                  -----            -------
     GENERAL OPTIONS
     AllowDownload	       yes|no		yes
     AllowStream	       yes|no		yes
     AllowPlayLocally      yes|no           yes
     CheckStreamClient     yes|no		no
     ReadMP3Info	       yes|no		yes
     StreamTimeout         integer          0

     DIRECTORY OPTOINS
     BaseDir	       URL		/apache_mp3
     CacheDir              path             -none-
     HelpURL               URL              apache_mp3_help.gif:614x498
     StreamBase            URL              -none-

     DISPLAY OPTIONS
     ArrowIcon	       URL		right_arrow.gif
     CoverImage            filename         cover.jpg
     DescriptionFormat     string           -see below-
     DirectoryIcon	       URL		cd_icon_small.gif
     PlaylistIcon          URL              playlist.gif
     Fields                list             title,artist,duration,bitrate
     HomeLabel	       string		"Home"
     LongList	       integer		10
     PathStyle             Staircase|Arrows Staircase
     SongIcon	       URL		sound.gif
     SubdirColumns	       integer		3
     Stylesheet	       URL		apache_mp3.css
     TitleIcon	       URL		cd_icon.gif

General Configuration Variables
-------------------------------

AllowDownload *yes|no*
     You may wish for users to be able to stream songs but not download
     them to their local disk.  If you set AllowDownload to "no",
     Apache::MP3 will not generate a download link for MP3 files.  It will
     also activate some code that makes it inconvenient (but not
     impossible) for users to download the MP3s.

     The module recognizes the arguments "yes", "no", "true" and "false".
     The default is "yes".

     Note that this setting only affects MP3 files.  Other files, including
     cover art and playlists, can still be downloaded.

AllowStream *yes|no*
     If you set AllowStream to "no", users will not be able to stream songs
     or generate playlists.  I am not sure why one would want this feature,
     but it is included for completeness.  The default is "yes."

AllowPlayLocally *yes|no*
     If you set AllowPlayLocally to "yes", then the playlists generated by
     the module will point to the physical files when handling requests
     from a user that happens to be working on the same machine.  This is
     more efficient, and allows the user to pause playback, fast forward,
     and so on.  Otherwise, the module will treat local users and remote
     users the same.  The default is "no".

CheckStreamClient *yes|no*
     Setting CheckStreamClient to "yes" enables code that checks whether
     the client claims to be able to accept streaming MPEG data.  This
     check isn't foolproof, but supports at least the most popular MP3
     decoders (WinAmp, RealPlayer, xmms, mpg123).  It also makes it harder
     for users to download songs by pretending to be a streaming player.

     The default is "no".

ReadMP3Info *yes|no*
     This controls whether to extract field information from the MP3
     files.  The default is "yes".

     If "no" is specified, all fields in the directory listing will be
     blank except for filename and description, which will both be set to
     the physical filename of the MP3 file.

StreamTimeout integer
     For demo mode, you can specify a stream timeout in seconds.
     Apache::MP3 will cease streaming the file after the time specified.
     Because this feature uses the average bitrate of the song, it may be
     off by a second or two when streaming variable bitrate MP3s.

Configuration Variables Affecting Paths and Directories
-------------------------------------------------------

BaseDir URL
     The BaseDir variable sets the URL in which Apache::MP3 will look for
     its icons and stylesheet.  You may use any absolute local or remote
     URL. Relative URLs are not accepted.

     The default is "/apache_mp3."

CacheDir path
     This variable sets the directory path for Apache::MP3's cache of MP3
     file information.  This must be an absolute path in the physical file
     system and be writable by Apache.

HelpURL *URL:widthxheight*
     The URL of the page to display when the user presses the "Quick Help
     Summary" link at the bottom of the page.  In the current
     implementation, the module pops up a plain window containing a
     marked-up GIF of a typical page. You can control the size of this page
     by adding ":WxH" to the end of the URL, where W and H are the width
     and height, respectively.

     Default: apache_mp3_help.gif:614x498

     Note: I prepared this image on an airplane, so it isn't as clean as I
     would like.  Volunteers to make a better help page are welcomed!

StreamBase URL
     A URL to use as the base for streaming.  The default is to use the
     same host for both directory listings and streaming.  This may be of
     use for transparent reverse proxies or for situations in which you
     want one server to generate the index, and the other to service the
     stream requests.

     Example:

     If the song requested is
     http://www.foobar.com/Songs/Madonna_live.m3u?stream=1

     and StreamBase is set to *http://streamer.myhost.net*, then the URL
     placed in the playlist will be

          http://streamer.myhost.net/Songs/Madonna_live.m3u?stream=1

     The path part of the URL is simply appended to StreamBase.  If you
     want to do more sophisticated URL processing, use *mod_rewrite* or
     equivalent.

Configuration Variables Affecting the Visual Display
----------------------------------------------------

ArrowIcon URL
     Set the icon used for the arrows displayed between the components of
     the directory path at the top of the directory listing.

CoverImage filename
     Before displaying a subdirectory, Apache::MP3 will look inside the
     directory for an image file.  This feature allows you to display
     digitized album covers or other customized icons.  The default is
     "cover.jpg", but the image file name can be changed with CoverImage.
     If the file does not exist, the image specified by TitleIcon will be
     displayed instead.

DescriptionFormat string
     The "Description" field, which is used both in the Description column
     of the directory index and in the metadata sent to the player during
     streaming, has a default format of title-artist-album.  The
     description is constructed in such a way that the hyphen is omitted if
     the corresponding field of the song's MP3 tag is empty.

     You can customize this behavior by providing a DescriptionFormat
     string.  These strings combine constant characters with %x format
     codes in much the way that sprintf() does.  For example, the directive
     shown below will create descriptions similar to *[Madonna] Like a
     Virgin (1980)*.

          PerlSetVar DescriptionFormat "[%a] %t (%y)"

     The full list of format codes follows:

     Table 2: DescriptionFormat Field Codes

          Code         Description
          ----         -----------

          %a	       Artist name
          %c	       Comment
          %d	       Duration, in format 00m00s
          %f	       Name of physical file (minus path)
          %g	       Genre
          %l	       Album name
          %m	       Minutes portion of duration, usually used with %s
          %n	       Track number
          %q	       Sample rate, in kHz
          %r	       Bitrate, in kbps
          %s	       Seconds portion of duration, usually used with %m
          %S	       Duration, expressed as total seconds
          %t	       Title
          %y	       Year

DirectoryIcon URL
     Set the icon displayed next to subdirectories in directory listings,
     "cd_icon_small.gif" by default.

PlaylistIcon URL
     Set the icon displayed next to playlists in the playlist listings,
     "playlist.gif" by default.

Fields *title,artist,duration,bitrate*
     Specify what MP3 information fields to display in the song listing.
     This should be a list delimited by commas, "|" symbols, or any other
     non-word character.

     The following are valid fields:

     Table 3: Field Names For use with the Fields Configuration Variable

          Field        Description
          -----        -----------

          album	 The album
          artist       The artist
          bitrate      The bitrate, expressed in kbps
          comment      The comment field
          duration     Duration of the song in hour, minute, second format
          description	 Description as specified by DescriptionFormat
          filename	 The physical name of the .mp3 file
          genre        The genre
          min          The minutes portion of the duration
          seconds      Total duration of the song in seconds
          sec          The seconds portion of the duration
          samplerate   The sampling rate, in KHz
          title        The title of the song
          track	 The track number
          year         The album year

     Note that MP3 rip and encoding software differ in what fields they
     capture and the exact format of such fields as the title and album.
     Field names are case insensitive.

     Previous versions of this module used "kbps" instead of "bitrate".
     This has been changed.

HomeLabel string
     This is the label for the link used to return to the site's home
     page.  You may use plain text or any fragment of HTML, such as an
     <IMG> tag.

LongList integer
     The number of lines in the list of MP3 files after which it is
     considered "long".  In long lists, the control buttons are placed at
     the top as well as at the bottom of the table.  Defaults to 10.

PathStyle *Staircase|Arrows*
     Controls the style with which the parent directories are displayed.
     The options are "Staircase" (the default), which creates a
     staircase-style display (each child directory is on a new line and
     offset by 0.3 em).  The other is "Arrows", in which the entire
     directory list is on a single line and separated by graphic arrows.
     Try them both and choose the one you prefer.

SongIcon URL
     Set the icon displayed at the beginning of each line of the MP3 file
     list, "sound.gif" by default.

SubdirColumns integer
     The number of columns in which to display subdirectories (the small
     "CD icons").  Default 3.

PlaylistColumns integer
     The number of columns in which to display playlists. Default 3.

Stylesheet URL
     Set the URL of the cascading stylesheet to use, "apache_mp3.css" by
     default.  If the URL begins with a slash it is treated as an absolute
     URL.  Otherwise it is interpreted as relative to the BaseDir
     directory.

TitleIcon URL
     Set the icon displayed next to the current directory's name in the
     absence of a coverimage, "cd_icon.gif" by default.  In this, and the
     other icon-related directives, relative URLs are treated as relative
     to BaseDir.

Stylesheet-Based Configuration
------------------------------

   You can change the appearance of the page by changing the cascading
stylesheet that accompanies this module, *apache_mp3.css*.  The following
table describes the tags that can be customized:

   Table 4: Stylesheet Class Names

     Class Name           Description
     ----------           ----------

     BODY                 General defaults
     H1                   Current directory path
     H2                   "CD Directories" and "Song List" headings
     TR.title             Style for the top line of the song listing
     TR.normal            Style for odd-numbered song listing lines
     TR.highlight         Style for even-numbered song listing lines
     .directory           Style for the title of the current directory
     .subdirectory        Style for the title of subdirectories
     P                    Ordinary paragraphs
     A                    Links
     INPUT                Fill-out form fields

Subclassing this Module
-----------------------

   For more extensive customization, you can subclass this module.  The
Apache::MP3::Sorted module illustrates how to do this.

   Briefly, your module should inherit from Apache::MP3 (or
Apache::MP3::Sorted) either by setting the `@ISA' package global or, in
Perl 5.6 and higher, with the `use base' directive.  Your module can then
override existing methods and define new ones.

   This module uses the mod_perl method invocation syntax for handler
invocation.  Because of this, if you override the handler() method, be
sure to give it a prototype of ($$).  If you override new(), be sure to
place the Apache::Request object in an instance variable named 'r'.  See
the MP3.pm module for details.

   One implication of using the method invocation syntax is that the
Apache::MP3 object is created at server configuration time.  This means
that you cannot tweak the code and simply restart the server, but must
formally stop and relaunch the server every time you change the code or
install a new version.  This disadvantage is balanced by a savings in
memory consumption and performance.

   See The Apache::MP3 API below for more information on overriding
Apache::MP3 methods.

Linking to this module
======================

   You may wish to create links to MP3 files and directories manually.
The rules for creating HREFs are different from those used in earlier
versions of Apache::MP3, a decision forced by the fact that the playlist
format used by popular MP3 decoders has changed.

   The following rules apply:

Download an MP3 file
     Create an HREF using the unchanged name of the MP3 file.  For example,
     to download the song at /songs/Madonna/like_a_virgin.mp3, use:

          <a href="/Songs/Madonna/like_a_virgin.mp3">Like a Virgin</a>

Stream an MP3 file
     Replace the MP3 file's extension with .m3u and add the query string
     "play=1".  Apache::MP3 will generate a playlist for the streaming MP3
     decoder to load.  Example:

          <a href="/Songs/Madonna/like_a_virgin.m3u?play=1">
                  Like a streaming Virgin</a>

Stream a directory
     Append "/playlist.m3u?Play+All=1" to the end of the directory name:

          <a href="/Songs/Madonna/playlist.m3u?Play+All=1">Madonna Lives!</a>

     The capitalization of "Play All" is significant.  Apache::Mp3 will
     generate a playlist containing all MP3 files within the directory.

Stream a directory heirarchy recursively
     Append "/playlist.m3u?Play+All+Recursive=1" to the end of the
     directory name:

          <a href="/Songs/HipHop/playlist.m3u?Play+All+Recursive=1">Rock me</a>

     The capitalization of "Play All Recursive" is significant.
     Apache::MP3 will generate a playlist containing all MP3 files within
     the directory and all its subdirectories.

Shuffle and stream a directory
     Append "/playlist.m3u?Shuffle+All=1" to the end of the directory name:

          <a href="/Songs/HipHop/playlist.m3u?Shuffle+All">Rock me</a>

     Apache::MP3 will generate a playlist containing all MP3 files within
     the directory and all its subdirectories, and then randomize its
     order.

Shuffle an entire directory heirarchy recursively
     Append "/playlist.m3u?Shuffle+All+Recursive=1" to the end of the
     directory name:

          <a href="/Songs/HipHop/playlist.m3u?Shuffle+All+Recursive=1">Rock me</a>

     Apache::MP3 will generate a playlist containing all MP3 files within
     the directory and all its subdirectories, and then randomize its
     order.

Play a set of MP3s within a directory
     Append "/playlist.m3u?Play+Selected=1;file=file1;file=file2..." to the
     directory name:

          <a
          href="/Songs/Madonna/playlist.m3u?Play+Selected=1;file=like_a_virgin.mp3;file=evita.mp3">
          Two favorites</a>

     Again, the capitalization of "Play Selected" counts.

Display a sorted directory
     Append "?sort=field" to the end of the directory name, where field is
     any of the MP3 field names:

          <a href="/Songs/Madonna/?sort=duration">Madonna lives!</a>

The Apache::MP3 API
===================

   The Apache::MP3 object is a blessed hash containing a single key, r,
which points at the current request object.  This can be retrieved
conveniently using the r() method.

   Apache::MP3 builds up its directory listing pages in pieces, using a
hierarchical scheme.  The following diagram summarizes which methods are
responsible for generating the various parts.  It might help to study it
alongside a representative HTML page:

     list_directory()
     -------------------------  page top --------------------------------
        directory_top()

     <CDICON> <DIRECTORY> -> <DIRECTORY> -> <DIRECTORY>
     [Shuffle All] [Stream All]

     list_subdirs()

     subdir_list_top()
     ------------------------------------------------------------
     <CD Directories (6)>

     subdir_list()
           <cdicon> <title>   <cdicon> <title>  <cdicon> <title>
           <cdicon> <title>   <cdicon> <title>  <cdicon> <title>

     subdir_list_bottom()  # does nothing
     ------------------------------------------------------------

     list_playlists()

     playlist_list_top()
     ------------------------------------------------------------
     <CD Playlists (6)>

     playlist_list()
           <cdicon> <title>   <cdicon> <title>  <cdicon> <title>
           <cdicon> <title>   <cdicon> <title>  <cdicon> <title>

     playlist_list_bottom()  # does nothing
     ------------------------------------------------------------

     list_mp3s()
          mp3_list_top()
          ------------------------------------------------------------
          <Song List (4)>

     mp3_list()
         mp3_list_top()
           mp3_table_header()
              <Select>                  Title          Kbps

     format_song() # called for each row
        <icon>[] [fetch][stream]  Like a virgin  128
        <icon>[] [fetch][stream]  American Pie   128
        <icon>[] [fetch][stream]  Santa Evita     96
        <icon>[] [fetch][stream]  Boy Toy        168

     mp3_list_bottom()
       [Play Selected] [Shuffle All] [Play All]

     directory_bottom()
      -------------------------  page bottom -----------------------------

Method Calls
------------

   This section lists each of the Apache::MP3 method calls briefly.

$response_code = handler($request)
     This is a the standard mod_perl handler() subroutine.  It creates a
     new Apache::MP3 object, and then invokes its run() method.

$mp3 = Apache::MP3->new(@args)
     This is a constructor.  It stores the passed args in a hash and
     returns a new Apache::MP3 object.  If a single argument is passed it
     assumes that it is an Apache::Request object and stores it under the
     key "r".  You should not have to modify this method.

$request = $mp3->r()
     Return the stored request object.

$boolean = $mp3->is_local()
     Returns true if the requesting client is on the same machine as the
     server.

$response_code = $mp3->run()
     This is the method that interprets the CGI parameters and dispatches
     to the routines that draw the directory listing, generate playlists,
     and stream songs.

$response_code = $mp3->process_directory($dir)
     This is the top-level method for generating the directory listing.  It
     performs various consistency checks on the passed directory URL and
     returns an Apache response code.  The list_directory() method actually
     does most of the formatting work.

$response_code = $mp3->download_file($file)
     This method is called to download a file (not stream it).  It is
     passed the URL of the requested file and returns an Apache response
     code.  It checks whether downloads are allowed and if so allows Apache
     to take its default action.

$response_code = $mp3->stream($file)
     This method is called to stream an MP3 file.  It is passed the URL of
     the requested file and returns an Apche response code.  It checks
     whether streaming is allowed and then passes the request on to
     send_stream().

$mp3->send_playlist($urls,$shuffle)
     This method generates a playlist that is sent to the browser.  It is
     called from various places.  `$urls' is an array reference containing
     the MP3 URLs to incorporate into the playlist, and `$shuffle' is a
     flag indicating that the order of the playlist should be randomized
     prior to sending it.  No return value is returned.

$mp3_info = $mp3->find_mp3s($recurse)
     This method searches for all MP3 files in the currently requested
     directory.  `$recurse', if true, causes the method to recurse through
     all subdirectories.  The return value is a hashref in which the keys
     are the URLs of the found MP3s, and the values are hashrefs containing
     the MP3 tag fields recovered from the files ("title", etc.).

@urls = $mp3->sort_mp3s($mp3_info)
     This method sorts the hashref of MP3 files returned from find_mp3s(),
     returning an array.  The implementation of this method in Apache::MP3
     sorts by physical file name only.  Apache::MP3::Sorted has a more
     sophisticated implementation.

@mp3s = $mp3->load_playlist($playlist)
     This method loads a playlist file (.m3u) from disk and returns a list
     of MP3 files contained in the playlist.

$mp3->playlist_list_bottom($playlists)
     This method generates the footer at the bottom of the list of
     playlists given by `$playlists'. Currently it does nothing.

$mp3->playlist_list($playlists)
     This method displays the playlists given by `$playlists' in a nicely
     formatted table.

$html = $mp3->format_playlist($playlist)
     This method formats the indicated playlist by creating a fragment of
     HTML containing the playlist icon, the stream links and the playlist
     name. It returns a HTML fragment used by playlist_list().

$response_code = $mp3->list_directory($dir)
     This is the top level formatter for directory listings.  It is passed
     the URL of a directory and returns an Apache response code.

$mp3->directory_top($dir)
     This method lists the top part of the directory, including the title,
     the directory navigation list, and the big CD Icon in the upper left.

$mp3->generate_navpath_staircase($dir)
     This method generates the list of parent directories, displaying them
     as links so that the user can navigate.  It takes the URL of the
     current directory and returns no result.

$mp3->generate_navpath_arrows($dir)
     This method does the same, except that the parent directories are
     displayed on a single line, separated by arrows.

$mp3->directory_bottom($dir)
     This method generates the bottom part of the directory listing,
     including the module attribution and help information.

$mp3->subdir_list_top($directories)
     This method generates the heading at the top of the list of
     subdirectories.  `$directories' is an arrayref containing the
     subdirectories to display.

$mp3->subdir_list_bottom($directories)
     This method generates the footer at the bottom of the list of
     subdirectories given by `$directories'.  Currently it does nothing.

$mp3->subdir_list($directories)
     This method invokes sort_subdirs() to sort the subdirectories given by
     `$directories' and displays them in a nicely-formatted table.

@directories = $mp3->sort_subdirs($directories)
     This method sorts the subdirectories given in `$directories' and
     returns a sorted list (not an arrayref).

$html = $mp3->format_subdir($directory)
     This method formats the indicated subdirectory by creating a fragment
     of HTML containing the little CD icon, the shuffle and stream links,
     and the subdirectory's name.  It returns an HTML fragment used by
     subdir_list().

$mp3->get_help
     This subroutine generates the "Quick Help Summary" link at the bottom
     of the page.

$mp3->list_subdirs($subdirectories)
     This is the top-level subroutine for listing subdirectories (the part
     of the page in which the little CD icons appears).  `$subdirectories'
     is an array reference containing the subdirectories to display

$mp3->list_playlists($playlists)
     This is the top-level subroutine for listing playlists. `$playlists'
     is an array reference containing the playlists to display.

$mp3->list_mp3s($mp3s)
     This is the top-level subroutine for listing MP3 files.  `$mp3s' is a
     hashref in which the key is the path of the MP3 file and the value is
     a hashref containing MP3 tag info about it.  This generates the
     buttons at the top of the table and then calls mp3_table_header() and
     mp3_list_bottom().

$mp3->mp3_table_header
     This creates the first row (table headers) of the list of MP3 files.

$mp3->mp3_list_bottom($mp3s)
     This method generates the buttons at the bottom of the MP3 file
     listing. `$mp3s' is a hashref containing information about each file.

$mp3->mp3_list($mp3s)
     This routine sorts the MP3 files contained in `$mp3s' and invokes
     format_song() to format it for the table.

@buttons = $mp3->control_buttons
     Return the list of buttons printed at the bottom of the MP3 file
     listing.

$arrayref = $mp3->format_song($song,$info,$count)
     This method is called with three arguments.  `$song' is the path to
     the MP3 file, $info is a hashref containing tag information from the
     song, and $count is an integer containing the song's position in the
     list (which currently is unusued).  The method invokes
     format_song_controls() and format_song_fields() to generate a list of
     elements to be incorporated into cells of the table, and returns an
     array reference.

@array = $mp3->format_song_controls($song,$info,$count)
     This method is called with the same arguments as format_song().  It
     returns a list (not an arrayref) containing the "control" elements of
     one row of the MP3 list.  The control elements are all the doo-dads on
     the left-hand side of the display, including the music icon, the
     checkbox, and the [fetch] and [stream] links.

@array = $mp3->format_song_fields($song,$info,$count)
     This method is called with the same arguments as format_song().  It
     returns a list (not an arrayref) containing the rest of a row of the
     MP3 file display.  This will include the title, artist, and so forth,
     depending on the values of the Fields configuration. variable.

($directories,$mp3s) = $mp3->read_directory($dir)
     This method reads the directory in $dir, generating an arrayref
     containing the subdirectories and a hashref containing the MP3 files
     and their information, which are returned as a two-element list.

$hashref = $mp3->fetch_info($file)
     This method fetches the MP3 information for $file and returns a
     hashref containing the MP3 tag information as well as some synthesized
     fields.  The synthesized fields are track, which contains the same
     information as tracknum; description, which contains the title, album
     and artist merged together; and *duration*, which contains the
     duration of the song expressed as hours, minutes and seconds.  Other
     fields are taken directly from the MP3 tag, but are downcased (for
     convenience to other routines).

Apache::MP3->path_escape($scalarref)
     This is a limited form of CGI::escape which does not escape the slash
     symbol ("/").  This allows URIs that correspond to directories to be
     escaped safely.  The escape is done inplace on the passed scalar
     reference.

@fields = $mp3->fields
     Return the fields to display for each MP3 file.  Reads the Fields
     configuration variable, or uses a default list.

$hashref = $mp3->read_cache($file)
     Reads the cache for MP3 information about the indicated file.  Returns
     a hashref of the same format used by fetch_info().

$boolean = $mp3->write_cache($file,$info)
     Writes MP3 information to cache.  $file and $info are the path to the
     file and its MP3 tag information, respectively.  Returns a boolean
     indicating the success of the operation.

$result_code = $mp3->send_stream($file,$uri)
     The send_stream() method generates an ICY (shoutcast) header for the
     indicated file (given by physical path $file and URI $uri) and
     streams it to the client.  It returns an Apache result code indicating
     the success of the operation.

$boolean = $mp3->download_ok
     Returns true if downloading files is allowed.

$boolean = $mp3->stream_ok
     Returns true if streaming files is allowed.

$boolean = $mp3->check_stream_client
     Returns true if the module should check the browser/MP3 player for
     whether it accepts streaming.

$boolean = $mp3->is_stream_client
     Returns true if this MP3 player can accept streaming.  Note that this
     is not a foolproof method because it checks a variety of
     non-standardized headers and user agent names!

$boolean = $mp3->read_mp3_info
     Returns true if the module should read MP3 info (true by default).

$seconds = $mp3->stream_timeout
     Returns the number of seconds after which streaming should time out.
     Used for "demo mode".

$lines = $mp3->file_list_is_long
     Returns the number of lines in the MP3 file listing after which the
     list is considered to be "long".  When a long list is encountered, the
     module places the control buttons at both the top and bottom of the
     MP3 file table, rather than at the bottom only.  This method

$html = $mp3->home_label
     Returns a fragment of HTML to use as the "Home" link in the list of
     parent directories.

$style = $mp3->path_style
     Returns the style of the list of parent directories.  Either "arrows"
     or "staircase".

$path = $mp3->cache_dir
     Returns the directory for use in caching MP3 tag information

$int = $mp3->subdir_columns
     Returns the number of columns to use in displaying subdirectories
     (little CD icons).

$dir = $mp3->default_dir
     Returns the base directory used for resolving relative paths in the
     directories to follow.

miscellaneous directories and files
     The following methods return the values of their corresponding
     configuration variables, resolved against the base directory, if need
     be:

          stylesheet()   URI to the stylesheet file
          parent_icon()	URI to the icon to use to move up in directory
                              hierarchy (no longer used)
          cd_icon        URI for the big CD icon printed in the upper left corner
          cd_list_icon   URI for the little CD icons in the subdirectory listing
          playlist_icon  URI for the playlist icon
          song_icon	URI for the music note icons printed for each MP3 file
          arrow_icon	URI for the arrow used in the navigation bar
          help_url	URI of the document to display when user asks for help

$boolean = $mp3->skip_directory($dir)
     This method is called during directory listings.  It returns true if
     the directory should not be displayed.  Currently it skips directories
     beginning with a dot and various source code management directories.
     You may subclass this to skip over other directories.

BUGS
====

   Although it is pure Perl, this module relies on an unusual number of
compiled modules.  Perhaps for this reason, it appears to be sensitive to
certain older versions of modules.

Can't find Apache::File at run time
-----------------------------------

   David Wheeler <dwheeler@salon.com> has reported problems relating to
Apache::File, in which the module fails to run, complaining that it can't
find Apache::File in @INC.  This affects Apache/1.3.12 mod_perl/1.24.
Others have not yet reported this problem.  This can be worked around by
replacing all occurrences of Apache::File with IO::File.

Random segfaults in httpd children
----------------------------------

   Before upgrading to Apache/1.3.6 mod_perl/1.24, I would see random
segfaults in the httpd children when using this module.  This problem
disappeared when I installed a newer mod_perl.

   If you experience this problem, I have found that one workaround is to
load the MP3::Info module at server startup time using the mod_perl
perl.startup script made the problem go away.  This is an excerpt from my
perl.startup file:

     # the !/usr/local/bin/perl
     ...
     use Apache::Registry ();
     use Apache::Constants();
     use MP3::Info;
     use Apache::MP3;
     use CGI();
     use CGI::Carp ();

Can't use -d $r->finfo
----------------------

   Versions of mod_perl prior to 1.22 crash when using the idiom -d
$r->finfo (or any other idiom).  Since there are many older versions still
out there, I have replaced $r->finfo with $r->filename and marked their
locations in comments.  To get increased performance, change back to
$r->finfo.

Misc
----

   In the directory display, the alignment of subdirectory icon with the
subdirectory title is a little bit off.  I want to move the title a bit
lower using some stylesheet magic.  Can anyone help?

SEE ALSO
========

   *Note Apache/MP3/Sorted: Apache/MP3/Sorted,, *Note Apache/MP3/Playlist:
Apache/MP3/Playlist,, *Note MP3/Info: MP3/Info,, *Note Apache: Apache,

ACKNOWLEDGEMENTS
================

   Tim Ayers <tayers@bridge.com> found and fixed a misfeature in the way
that playlists were sorted.

   Chris Nandor identified various bugs in the module and provided patches.

AUTHOR
======

   Copyright 2000, Lincoln Stein <lstein@cshl.org>.

   This module is distributed under the same terms as Perl itself.  Feel
free to use, modify and redistribute it as long as you retain the correct
attribution.


