#!/usr/bin/perl use XML::Parser; use DBI; $mythtv_database = "mythconverg"; $mythtv_hostname = "localhost"; $mythtv_user = "mythtv"; $mythtv_password = "mythtv"; $mythtv_playlist_host = "THIS SHOULD BE YOUR PC's HOSTNAME"; $file = "/mnt/store/music/library.xml"; sub trim { $_ = $_[0]; s/^\s+//o; s/\s+$//o; return $_; } sub start_element { my ($self, $element) = @_; push(@current_xml_elements, $element); } sub end_element { my ($self, $element) = @_; if($element ne pop(@current_xml_elements)) { print "Unexpected name ".($element)." for popped element\n"; } if($element eq 'key') { push(@current_plist_elements, trim($tag_data)); } elsif($element eq 'integer' || $element eq 'string' || $element eq 'dict' || $element eq 'date' || $element eq 'true' || $element eq 'false' || $element eq 'array' || $element eq 'data') { if($current_xml_elements[$#current_xml_elements] ne "array") { $finished_plist_element = pop(@current_plist_elements); } else { $finished_plist_element = $current_plist_elements[$#current_plist_elements]; } plist_element($finished_plist_element, $element, trim($tag_data)); } $tag_data = ''; } sub characters { my ($self, $data) = @_; $tag_data .= $data; } sub plist_element { my ($element_name, $element_type, $element_data) = @_; if($current_plist_elements[0] eq 'Tracks') { if($element_name eq 'Name') { $name = $element_data; } elsif($element_name eq 'Artist') { $artist = $element_data; } elsif($element_name eq 'Album') { $album = $element_data; } elsif(($element_name eq 'Disabled' || $element_name eq 'Has Video') && $element_type eq 'true') { $disabled = 1; } elsif($element_type eq 'dict') { if($name && $artist && !$disabled) { if(!$dbh) { $dbh = DBI->connect("DBI:mysql:database=".$mythtv_database.";host=".$mythtv_hostname, $mythtv_user, $mythtv_password); $dbh->do("LOCK TABLES music_playlists WRITE, music_songs READ, music_artists READ, music_albums READ"); $sql = "select song_id from music_songs join music_artists on music_songs.artist_id = music_artists.artist_id join music_albums on music_songs.album_id = music_albums.album_id WHERE name = ? AND artist_name = ? ORDER BY album_name = ? DESC"; $get_id = $dbh->prepare( $sql ); $dbh->do("DELETE FROM music_playlists WHERE playlistid > 2"); $mythtv_playlist_host_quoted = $dbh->quote($mythtv_playlist_host); } #print "name: $name , artist: $artist , album: $album\n"; $get_id->execute($name, $artist, $album); if(($id) = $get_id->fetchrow_array()) { $track_map[$element_name] = $id; } else { print "Could not map $artist - $name ($album) ID:$id\n"; } $get_id->finish(); } $name = $artist = $album = $disabled = undef; } } elsif($current_plist_elements[0] eq 'Playlists') { if($element_name eq 'Name') { $name = $element_data; } elsif($element_name eq 'Track ID') { if($track_map[$element_data]) { $tracks .= ",".$track_map[$element_data]; } } elsif($element_name eq 'Playlists' && $element_type eq 'dict') { if($tracks) { $values .= ",(NULL, ".($dbh->quote($name)).", ".$mythtv_playlist_host_quoted.", ".($dbh->quote(substr($tracks, 1))).")"; } $name = $tracks = $undef; } } elsif($element_name eq 'Playlists' && $element_type eq 'array') { $dbh->do("INSERT INTO music_playlists (playlist_id, playlist_name, hostname, playlist_songs) VALUES ".substr($values, 1)); $dbh->do("UNLOCK TABLES"); } } my $parser = new XML::Parser(Handlers => {Start => \&start_element, End => \&end_element, Char => \&characters}); $parser->parsefile($file);