summaryrefslogtreecommitdiff
path: root/cgi-bin/Search.pm
diff options
context:
space:
mode:
Diffstat (limited to 'cgi-bin/Search.pm')
-rw-r--r--cgi-bin/Search.pm307
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;
+}