########################################################################## ## All portions of this code are copyright (c) 2003,2004 nethype GmbH ## ########################################################################## ## Using, reading, modifying or copying this code requires a LICENSE ## ## from nethype GmbH, Franz-Werfel-Str. 11, 74078 Heilbronn, ## ## Germany. If you happen to have questions, feel free to contact us at ## ## license@nethype.de. ## ########################################################################## =head1 NAME PApp::MimeType - analyze and normalize mimetypes and extensions =head1 SYNOPSIS use PApp::MimeType; my $mt = (PApp::MimeType::by_extension "jpg")->mimetype; =head1 DESCRIPTION Looks up mime types and file extensions, and gives hints which file extension would be most commonly used. All mimetypes and extensions returned by this module are in lowercase. Matches done by this module are done in a case-independent-manner. =cut package PApp::MimeType; use base Exporter; $VERSION = 1.43; @EXPORT_OK = qw(by_extension by_filename by_mimetype clear_mimedb load_mimedb); my %by_extension; my %by_mimetype; =head2 Lookup Functions These functions look up (existing) mimetype objects and return it. Watch out, they are not constructors, so either import them to your namespace or call them like functions (C). =over 4 =item PApp::MimeType::by_extension $file_extension Return a C object by guessing from the file extension (leading dots are stripped). If no entry could be found for that specific extension, returns undef. To get a guarenteed mimetype for any file, use something like this: my $content_type = (PApp::MimeType::by_extension $ext or PApp::MimeType::by_mimetype "application/octet-stream") ->mimetype; =item PApp::MimeType::by_filename $path Like C, but strips the filename part away first. =item PApp::MimeType::by_mimetype $mimetype Return a C object by it's mimetype (e.g. "image/jpeg"). Return C if none could be found. =cut sub by_extension($) { my $ext = lc $_[0]; %by_extension || load_mimedb(); while () { $by_extension{$ext} and return $by_extension{$ext}; $ext =~ s/^[^.]*\.// or return (); } } sub by_filename($) { my $path = $_[0]; by_extension +($path =~ /\.([^\/\\]+)$/ ? $1 : $path); } sub by_mimetype($) { my $mimetype = lc $_[0]; %by_mimetype || load_mimedb(); $by_mimetype{$mimetype}; } =back =head2 Methods C objects are immutable, and support a number of methods. =over 4 =item $type = $mt->mimetype Return the normalized mimetype as a string (e.g. "image/pjpeg" objects would return "image/jpeg"). =item @types = $mt->mimetypes Return all possible matching mimetypes. The default (suggested) mimetype is returned first. =item $extension = $mt->extension Return the default extension to use (the most common one) for this mimetype. =item @extensions = $mt->extensions Return all extensions possibly used by this mimetype, with more common ones first. =cut sub mimetype($) { $_[0][0][0]; } sub mimetypes($) { $_[0][0]; } sub extension($) { $_[0][1][0]; } sub extensions($) { $_[0][1]; } =back =head2 Database Functions The mime database is initialized on demand form a default file. If you want to overwrite or augment it, use the following functions: =over 4 =item clear_mimedb Clears the internal mimetypes database =item load_mimedb [$path] Appends the mime type data in the given file to the internal mimetypes database. If C<$path> is omitted, uses the system mimedb. The format of the mime database file is similar (but not identical) to the mime.types file used by many servers: MIMEDB := LINE* LINE := ( EMPTY | MIMERECORD ) COMMENT? NL COMMENT := '#' NON-NL* EMPTY := WS* MIMERECORD := MIMETYPES EXTENSIONS MIMETYPES := MIMETYPE ( ',' MIMETYPE )* EXTENSIONS := EXTENSION ( WS* EXTENSION )* EXTENSION := NON-WS-NON-DOT Mimetypes and extensions are sorted in the order of most-common ot least-common. Here is a simple example for text/plain text/plain txt asc Here is a more complicated example for image/jpeg, which also covers the wrong but commonly in use (MICROSOFT, DIE DIE DIE) pjpeg-type. image/jpeg,image/pjpeg jpg jpeg jpe pjpg pjpeg =cut sub clear_mimedb() { %by_extension = %by_mimetype = (); } sub load_mimedb(;$) { my $path = $_[0]; unless (defined $path) { require PApp::Config; $path = "$PApp::Config{LIBDIR}/etc/mimedb"; } open my $db, "<", $path or die "$path: $!"; while (<$db>) { s/^\s+//; s/(#.*)?[\015\012]*$//; if ($_ ne "") { my ($types, @exts) = split /\s+/; my @types = split /,/, $types; my $obj = bless [ [@types], [@exts] ]; $by_mimetype{lc $_} = $obj for @{$obj->[0]}; $by_extension{lc $_} = $obj for @{$obj->[1]}; } } } 1; =back =head1 SEE ALSO L. =head1 AUTHOR Marc Lehmann http://home.schmorp.de/ =cut