diff options
Diffstat (limited to 'cgi-bin/Search.pm')
| -rw-r--r-- | cgi-bin/Search.pm | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/cgi-bin/Search.pm b/cgi-bin/Search.pm new file mode 100644 index 0000000..af6b3fd --- /dev/null +++ b/cgi-bin/Search.pm @@ -0,0 +1,307 @@ +# included script to provide platter search +# artist, album, song, date, number of random tracks to take, +# scope (misc or album), inventory +# +# returns list of matching lines + +package Search; +use Globals; +use Globals qw(@CUSTOM); +use Globals qw($delim); +use Globals qw($debug); +use Globals qw(%PLATTERS); + +use strict; + +my $artist = undef; +my $title = undef; +my $album = undef; +my $dateFrom = undef; +my $dateTo = undef; +my $scope = undef; +my $random = undef; +my $exclTypes = undef; +my $exact = 0; +my $searchFor = undef; #artist|album|track +my @inv = (); +my @filter = (); +my %ABCS; + + +return 1; + +sub setArtist { + my ($thisartist) = @_; + $thisartist =~ s/^The //i; + $thisartist =~ s/, The$//i; + $artist = $thisartist; +} + +sub setTitle { + $title = $_[0]; +} + +sub setAlbum { + $album = $_[0]; +} + +sub setDateFrom { + ($dateFrom) = @_ unless ($_[0] =~ /^1900$/); +} + +sub setDateTo { + ($dateTo) = @_ unless ($_[0] =~ /^2525$/); +} + +sub setScope { + ($scope) = @_; + $scope = 'all' if (!$scope); +} + +sub setRandom { + ($random) = @_; +} + +sub setInv { + @inv = @_; +} + +sub setExact { + ($exact) = @_; +} + +sub setFilter { + @filter = @_; +} + +sub setExclTypes { + ($exclTypes) = @_; +} + +sub searchFor { + ($searchFor) = @_; +} + +sub go { + + my @result = (); + + #load abcs + if ($searchFor eq 'artist') { %ABCS = getABCs() } + + # decide if we can skip opening the inventories + my $pureArtistSearch = ($searchFor eq 'artist' && !$title && !$album && !$dateFrom && !$dateTo && $scope eq 'all'); + + # loop through each platter + @inv = keys %PLATTERS if (!defined @inv); + + foreach (@inv) { + my $platter = $_; + my $base; + + # Check the artist cache + if (open (ARTIST, "../inventory/".$platter.".artist")) { + my $useplatter; + while (<ARTIST>) { + chomp; + my $thisArtist = $_; + if (!$artist || + ($exact && # want exact match + $thisArtist =~ /^\Q$artist\E$/i) || + (!$exact && # not exact + $thisArtist =~ /\Q$artist\E/i)) { + if (!$exact && # but we weren't doing an exact search + $thisArtist =~ /^\Q$artist\E$/i && + $searchFor eq 'artist' && $artist) { # bail out just returning the artist name for redirect + return (makeNice($thisArtist)); + } + if ($pureArtistSearch) { # store in result + push (@result, makeABC($thisArtist)); + } + else { # examine this platter further + $useplatter = 1; + print "Using $platter\n" if ($debug); + last; + } + } + } + next if !$useplatter; + } + + if (!$pureArtistSearch) { # Only continue with full inv search if artist cache didn't populate the results + + # Open the inventory + + open (PLATTER, "../inventory/".$platter.".inv"); + while (<PLATTER>) { + chomp; + my $raw = $_; + if ($raw =~ /^http\:\/\//) { # is the base url + $base = $raw; + next; + } + + my ($folder, $trackartist, $trackalbum, $year, $track, $url) = split ($delim, $raw); + + # apply filter + my $filetype = substr($url, rindex($url, '.')+1); + next if ($exclTypes =~ /$filetype,/); + if ($#filter > -1) { + my $match = 0; + #print "$filetype\n"; + foreach( @filter ) { + if (/^$filetype$/i) { $match = 1; last; } + } + if (!$match) { next; } + } + + + # Match Scope + + if ($scope && $scope ne "all") { + if (length ($trackalbum) == 0) { + next if ($scope eq 'album'); + } + else { + next if ($scope eq 'misc'); + } + } + + # Match Track Title + if ($title) { + unless (($exact && # want exact match + $track =~ /^(\d{2} - |)\Q$title\E(\.[^\.]*|)$/i) + || + (!($exact) && # not exact + $track =~ /\Q$title\E/i)) { + next; + } + } + + # Match Artist + if ($artist) { + unless ($exact && # want exact match + ($folder =~ /^\Q$artist\E$/i || # artist folder + ($trackartist =~ /^\Q$artist\E$/i )) + # track artist (not on album searches) + || + (!($exact) && # not exact + ($folder =~ /\Q$artist\E/i || # artist folder + $trackartist =~ /\Q$artist\E/i))) { # track artist + next; + } + } + + # Set the album to misc if needed + if (!$trackalbum) { + $trackalbum = 'Miscellany'; + } + + # Match Album Title + if ($album) { + unless (($exact && # want exact match + ($trackalbum =~ /^\Q$album\E\//i || + $album =~ /^\Q$trackalbum\E(\/|$)/i)) # allow subfolders and parents + || + (!$exact && # not exact + $trackalbum =~ /\Q$album\E/i)) { + next; + } + } + + # Match Dates + + if (($dateFrom || $dateTo)) { + if (defined $year && (($dateFrom && $year < $dateFrom ) + || ($dateTo && $year > $dateTo ))) { + next; + } + } + + # Store Result + if ($searchFor eq 'artist') { + if ($folder) { + foreach (@CUSTOM) { + $folder = undef if (/^$folder$/) + } + if ($folder && + !($trackartist + && $scope eq 'misc')) {push(@result, makeABC($folder))} + } + if ($trackartist && + $trackartist ne $folder && + !($scope eq 'album')) { push(@result, makeABC($trackartist)); } + } + elsif ($searchFor eq 'album') { + my $partalbum = $trackalbum; + while ($partalbum =~ s/(.*)\/.+/$1/) { + my $parentalbum = $1; my $parentyear; + if ($parentalbum =~ / \((\d{4})\)(\/|)/) { + $parentyear = $1; + } + push(@result, "$parentyear$delim$parentalbum$delim$platter"); + } + # misc is always merged + my $albumline = "$year$delim$trackalbum$delim"; + $albumline.=$platter unless ($trackalbum eq "Miscellany"); + push(@result, $albumline); + } + elsif ($searchFor eq 'track') { + push(@result, "$raw$delim$platter"); + } + } + close PLATTER; + } + } + # remove duplicates from artist and album searches + #print join ("\n", keys %ABCS); + + @result = removeDup(@result) if ($searchFor ne 'track'); + # take random selection of results + if ($random>0) { + my %done; + my @randomlist; + + if ($random > $#result+1) { + $random = $#result+1; + } + + while ($random > 0) { + my $index; + do { + $index = int(rand($#result+1)); + } while (exists $done{$index}); + push(@randomlist, $result[$index]); + $done{$index} = 1; + $random--; + } + return @randomlist; + } + else { + return @result; + } +} + +sub removeDup( @_ ) { + my @result = sort( @_ ); + + my $last; + my $i=0; + while ($i<=$#result) { + if ($last eq $result[$i]) { + splice @result, $i, 1; + } + else { + $last = $result[$i]; + $i++; + } + } + return @result; +} + +sub makeABC( @_ ) { + my ($entry) = @_; + $entry =~ s/^\W*//; + if ($ABCS{$entry}) { $entry = ucfirst($ABCS{$entry}.$delim.$entry); } + return $entry; +} |
