#!/usr/bin/perl # # m3u2myth.pl # # m3u <==> MythMusic DB # created: 08/25/2003 # # Copyright (C) 2005 Joseph N. Mondloch # # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License version 2, # # as published by the Free Software Foundation # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # http://www.gnu.org/licenses/gpl.txt # # # # insert m3u playlist files into MythMusic DB # build m3u playlist files from MythMusic DB # # # Version: 0.02162005 use Getopt::Long; use DBI; use MP3::Info; #my $DBuser = 'mythtv'; my $DBuser = 'root'; my $DBpass = 'ms3308'; my $DBhost = 'localhost'; my $FEhost = 'localhost.localdomain'; my %playlist; my %playlistid; my $playlistname; my $filename; my $mode = 0; my $force = 0; my $dbh; my $test = 0; print "\n---------------------------------------\n"; print "m3u <==> MythMusic DB Conversion Script\n"; print "---------------------------------------\n\n"; GetOptions ( 'file=s' => \$filename, 'name=s' => \$playlistname, 'id=i' => \$playlistid, 'user=s' => \$DBuser, 'pass=s' => \$DBpass, 'host=s' => \$DBhost, 'fehost=s' => \$FEhost, 'list' => sub { $mode = 1; }, 'toDB' => sub { $mode = 2; }, 'toM3U' => sub { $mode = 3; }, 'force' => sub { $force = 1; }, 'Win2LinPath' => sub { $test = 1; }, ); if ($mode == 1) { $dbh = DBI->connect("dbi:mysql:database=mythconverg;host=$DBhost;user=$DBuser;password=$DBpass") || die "$DBI::errstr"; &listDB(); } elsif ($mode == 2) { $dbh = DBI->connect("dbi:mysql:database=mythconverg;host=$DBhost;user=$DBuser;password=$DBpass") || die "$DBI::errstr"; if (defined($filename) && defined($playlistname)) { &readM3U(); &writeDB(); } else { print "ERROR: --toDB requires: --file & --name\n"; } } elsif ($mode == 3) { $dbh = DBI->connect("dbi:mysql:database=mythconverg;host=$DBhost;user=$DBuser;password=$DBpass") || die "$DBI::errstr"; if (defined($filename) && defined($playlistid)) { &readDB($playlistid); &writeM3U($playlistid); } else { print "ERROR: --toM3U requires: --file & --id\n"; } } else { &showHelp(); } exit(0); sub showHelp { print "Usage:\n"; print " $0\n"; print " --list\t\t\t [list Playlists in DB]\n"; print " --toDB\t\t\t [Load m3u file into DB]\n"; print " --toM3U\t\t\t [Build m3u file from DB]\n"; print " --file \t\t [m3u playlist file]\n"; print " --id 'playlist id'\t\t [DB playlist id number]\n"; print " --force\t\t\t [Override File/DB entry exists errors]\n"; print " --name 'playlist name'\t [name for playlist (db/file)]\n"; print " --fehost 'hostname'\t\t [MythTV Frontend Hostname]\n"; print " --user 'username'\t\t [DB user -- Default: $DBuser]\n"; print " --pass 'password'\t\t [DB password -- Default: $DBpass]\n"; print " --host 'hostname'\t\t [DB host -- Default: $DBhost]\n"; print " --Win2LinPath \t\t [Convert \\path\\files to /path/files]\n"; } sub listDB { $sth = $dbh->prepare("SELECT playlistid,name,hostname FROM musicplaylist;"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; print "Current playlist(s) in DB:\n"; while($row = $sth->fetchrow_arrayref) { print "ID: $row->[0]\t Name: $row->[1]\t Host: $row->[2]\n"; } } sub readDB { my $playlistid = $_[0]; my @songids; print "Retrieving playlist: $playlistid...\n"; $sth = $dbh->prepare("SELECT name,songlist,hostname FROM musicplaylist WHERE playlistid=$playlistid;"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; while($row = $sth->fetchrow_arrayref) { $playlist{$playlistid}{'name'} = $row->[0]; @songids = split /,/, $row->[1]; $playlist{$playlistid}{'hostname'} = $row->[2]; } foreach(@songids) { if ($_ < 0) { print "Playlist contains sub-playlist ($_)...\n"; $playlist{$playlistid}{'songlist'} = $playlist{$playlistid}{'songlist'} . &readDB(0 - $_) . ","; } else { $playlist{$playlistid}{'songlist'} = $playlist{$playlistid}{'songlist'} . $_ . ","; } } chop($playlist{$playlistid}{'songlist'}); return($playlist{$playlistid}{'songlist'}); } sub writeDB { my $songlist; $sth = $dbh->prepare("SELECT * FROM musicplaylist WHERE name=\"$playlistname\" AND hostname=\"$FEhost\";"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; if ($sth->rows() > 0) { if ($force == 0) { print "DB: $playlistname already exists. Use --force to override.\n"; exit(1); } else { $sth = $dbh->prepare("DELETE FROM musicplaylist WHERE name=\"$playlistname\" AND hostname=\"$FEhost\";"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; } } foreach $file (@{ $playlist{'m3u'} }) { if ( $test == 1 ) { $file=~tr/\\/\//; } $sth = $dbh->prepare("SELECT intid FROM musicmetadata WHERE filename=\"$file\";"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; while($row = $sth->fetchrow_arrayref) { $songlist = $songlist . $row->[0] . ","; } } chop($songlist); print "Inserting new playlist to DB: $playlistname:$songlist\n"; $sth = $dbh->prepare("INSERT INTO musicplaylist (name,songlist,hostname) VALUES (\"$playlistname\",\"$songlist\",\"$FEhost\");"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; } sub readM3U { print "Reading data from m3u file...\n"; open(HAND, "$filename") || die("unable to open m3u file: $!"); while() { chomp; next if /^#EXT/; push @{ $playlist{'m3u'} }, $_; } close(HAND); } sub writeM3U { my $playlistid = $_[0]; print "Writing playlist ($playlist{$playlistid}{'name'}) to m3u file...\n"; my @songids = split /,/, $playlist{$playlistid}{'songlist'}; if ((-e $filename) && ($force == 0)) { print "FILE: $filename already exists. Use --force to override.\n"; exit(1); } open(HAND, ">$filename") || die("unable to open m3u output file: $!"); print HAND "#EXTM3U\n"; foreach(@songids) { $sth = $dbh->prepare("SELECT filename FROM musicmetadata WHERE intid=\"$_\";"); $sth->execute || die "Unable to execute query: $dbh->errstr\n"; while($row = $sth->fetchrow_arrayref) { my $mp3Tag = get_mp3tag($row->[0],2,1); my $mp3Info = get_mp3info($row->[0],2,1); $mp3Tag->{'TPE1'} =~ tr/\000-\010//d; $mp3Tag->{'TIT2'} =~ tr/\000-\010//d; print HAND "#EXTINF:" . int($mp3Info->{'SECS'}) . "," . $mp3Tag->{'TPE1'} . " - $mp3Tag->{'TIT2'}\n"; print HAND "$row->[0]\n"; } } close(HAND); }