#!/usr/bin/perl -T # Diese Datei MUSS 700-Filepermissions haben, da hier das FTP-Passwort # gespeichert wird! # # MP3-Archiv indizieren und in einer XML-Datei speichern # # ----- config vars my $mp3_dir = '/mp3z'; # rekursiv zu indizierendes Verzeichnis my $xmlbase = '/tmp/mp3_list.xml'; # Zielort der XML-Datei my $ping_host = 'foo.bar.de'; # vor Indexbeginn zu pingender Host my $ftp_user = 'www'; # FTP-User my $ftp_pass = 'strenggeheim'; # FTP-Passwd my $ftp_host = 'foo.bar.de'; # FTP-Remote-Host my $ftp_path = '/mymp3z'; # Zielverz. FTP-Server my $status_file = "/tmp/mp3_status"; # the status file # ----- public vars my (%change, %inode) = (); my @mp3z; # ----- used modules use strict; use MP3::Info; use MIME::QuotedPrint; use Net::FTP; use Net::Ping; use XML::Writer; # ----- some subs to check the necessarity of updating the database sub is_changed { $change{new} = 0; $inode{new} = 0; my $dummy; foreach (@mp3z) { ($change{cur}, $inode{cur}, $dummy) = split /;/, $_; $change{new} += $change{cur}; $inode{new} += $inode{cur}; } open (STATUS, "<$status_file") || return 1; ($change{old}, $inode{old}) = split /;/, ; close(STATUS); if (($change{new} == $change{old}) and ($inode{new} == $inode{old})) { return 0; } else { return 1; } } sub write_status { open (STATUS, ">$status_file") || die "Konnte Statusfile $status_file nicht anlegen!\n"; print STATUS $change{new} . ";" . $inode{new}; close (STATUS); } # ----- check via icmp ping whether remote host is reachable my $p = Net::Ping->new('icmp'); # requires root privileges ! if ($p->ping($ping_host, my $timeout) == 0) { print "exit: MP3-Fileserver nicht erreichbar!\n"; exit (); } # ----- save recursive directory listing into a hash (via BSD find) $ENV{'PATH'} = ""; open (PIPE, "/usr/bin/find $mp3_dir/* -path '/*/.*' -prune -o -iname '*.MP*' -printf \"%s;%i;%p\n\" |"); @mp3z = ; close (PIPE); if (!is_changed) { print "exit: Kein Update notwendig!\n"; exit (); } # ----- read mp3 information and write to xml file umask 002; my $xmlfile = new IO::File (">$xmlbase") or die $!; my $xml = new XML::Writer ( DATA_MODE => 1, DATA_INDENT => 2, OUTPUT => $xmlfile ); $xml->xmlDecl ("ISO-8859-1", "no"); $xml->doctype ("mp3archive", "", "mp3archive.dtd"); $xml->startTag("mp3archive"); my ($tag, $info); foreach my $mp3 (@mp3z) { $mp3 =~ s/.*;//g; chomp $mp3; $tag = get_mp3tag ($mp3); $info = get_mp3info ($mp3); $xml->startTag ("mp3", "filename" => encode_qp ($mp3), "year" => $tag->{'YEAR'}, "time" => $info->{'TIME'}); $xml->startTag ("artist"); $xml->characters (encode_qp ($tag->{'ARTIST'})); $xml->endTag ("artist"); $xml->startTag ("title"); $xml->characters (encode_qp ($tag->{'TITLE'})); $xml->endTag ("title"); $xml->endTag("mp3"); } $xml->endTag ("mp3archive"); $xml->end; $xmlfile->close(); # ----- write the status file write_status; # ----- put the created xml file onto the webserver via FTP my $fname = $xmlbase; my $dir = $xmlbase; $fname =~ s/(.*)\///g; my $myfname = $fname; $myfname =~ s/([^A-Za-z0-9_-].?)/\\$1/g; $dir =~ s/$myfname//g; chdir($dir); my $ftp = Net::FTP->new ($ftp_host, Debug => 0) || die "Keine FTP-Verbindung zum Webserver!\n"; $ftp->login ($ftp_user,$ftp_pass) || die "Fehler beim Einloggen via FTP!\n"; $ftp->cwd ($ftp_path); $ftp->put ($fname) || "Fehler beim Dateiupload auf FTP-Server!\n"; $ftp->quit () || "Fehler beim Ausloggen vom FTP-Server!\n";