Developer Forums | About Us | Site Map
Search  
HOME > TUTORIALS > SERVER SIDE CODING > PERL TUTORIALS > CULTURED PERL: FUN WITH MP3 AND PERL, PART 2


Sponsors





Useful Lists

Web Host
site hosted by netplex

Online Manuals

Cultured Perl: Fun with MP3 and Perl, Part 2
By Teodor Zlatanov - 2004-04-08 Page:  1 2 3 4 5 6

Initial searches

The FreeDB searches are done with the search criteria given earlier, either interactively or through command-line switches. Again, I use the %freedb_searches hash to make a list of searches. For each search, I specify the search words given by the user and add the words given to the -all switch. Note that each "word" can contain spaces; the words are single search units as far as autotag.pl and FreeDB are concerned.

Listing 4. Searching the FreeDB

foreach my $search (keys %freedb_searches)
{
 # @keywords will contain all the keywords (e.g. -artist "Pink Floyd")
 my @keywords = @{$config->get($search)};
 # we join in the -all keywords for every search
 push @keywords, @{$config->get(SEARCH_ALL)};

 print "Asked for keywords @keywords, search $search\n"
  if $config->DEBUG();
 # remember the searches and keywords done
 push @{$freedb_searches{$search}->{keywords}}, @keywords;

 # do the search
 foreach my $keyword (@keywords)
 {
  print "Searching with keyword $keyword, search $search\n"
   if $config->DEBUG();
  my %found_discs = $cddb->getdiscs($keyword, [$search]);

  if ($config->OR())                    # any search with OR
  {
   push @common, keys %found_discs;
  }
  elsif (scalar @common)                # second or more search without OR
  {
   my @new = keys %found_discs;
   my $lc = List::Compare->new(\@common, \@new);
   @common = $lc->get_intersection();
  }
  else                                  # first search without OR
  {
   @common = keys %found_discs
  }

  foreach my $disc (keys %found_discs)
  {
   $discs{$disc} = $found_discs{$disc};
   $disc_counts{$disc}++;       # we'll use this to remove matches later
  }
 }                              # foreach @keywords
}                               # foreach keys %freedb_searches

Once results are returned from the FreeDB database, they are put in the %found_disks hash. This hash is created for every keyword, so old results don't show up. When the -or switch is specified by the user, I simply add the results to the other results. Otherwise, the @common array is used to see what results are in common with previous results (the AND mode is implicit, meaning that by default search results must match all keywords requested). The List::Compare module is used to make an intersection of two lists. Doing it manually is possible and not too hard, but why spend the time and effort when a tested and probably much faster implementation already exists?

Note again that all search results are just string IDs that correspond to an album in the FreeDB database. Thus, I can use them as hash keys, lists of strings to be searched, etc.

Finally, I add the filtered results to the %discs hash, and increment the %disc_counts entry for each found album. The disk counts will be used later. Incidentally, I use "disc" instead of "disk" in variable names because that's what FreeDB uses.

When the results are all in place, I delete the ones that are not in @common. Recall that with -or, the @common array contains all the results.

Listing 5. Using @common to remove unwanted results; exit if none are wanted


foreach my $disc (keys %discs)
{
 next if grep { $_ eq $disc} @common;
 print "Deleting search result $disc, it was not in all searches\n"
  if $config->DEBUG();
 delete $discs{$disc};
}

unless (scalar keys %discs)
{
 print "The search you requested returned no discs, sorry.  Exiting.\n";
 exit;
}

The loop through the keys of %discs is simple, using grep() to see if a disc is in @common. I could have used a hash to optimize this loop further, but frankly I don't think it would have made a difference at all unless the user was finding hundreds of thousands of albums.

If no albums were left in %discs, I'm done and make a graceful exit with a message.



View Cultured Perl: Fun with MP3 and Perl, Part 2 Discussion

Page:  1 2 3 4 5 6 Next Page: Select the disks of interest

First published by IBM developerWorks


Copyright 2004-2017 GrindingGears.com. All rights reserved.
Article copyright and all rights retained by the author.