New Script Category: Fun/MP3/Rio

[email protected] (Howard Owen)
Newsgroups perl.scripts
Organization EGBOK Consultants
Message-ID <[email protected]>
I've got a script in search of a category. It's called 'riofill' and it is based
on an earlier script called 'riolist' by Ron Forrester <[email protected]>. riolist
generates a random playlist chosen so as to fit into the memory of a Diamond Rio 
PMP-300 portable MP3 player. It can upload the MP3 files mentioned in the playlist
to a connected Rio using the SBA 'rio' utility. I've added the pod documentation, 
complete with all the required fields for the script archive. I lack an appropriate 
category for this script however. I suggest that a 'Fun' category be created (as in 
the example script) and that riolist be placed in the 'Fun/MP3/Rio' category. In the 
interest of filling all your mailboxes with irrelevant spew, I've attached the script 
to this email. Actually  it's quite small and I include it so that someone can judge 
if I've met the structural requirements for uploading to the scripts archive. If I've 
violated etiquette, please flame me gently and I'll never do it again.  Ron and I are 
still discussing features for the script, so this version is not final.

Thanks,
-- 
Howard Owen [email protected]       Everything's Gonna Be OK Consulting
760 721-4820                    216 S. El Camino Real Oceanside CA 92054
I am not a pay TV service!      http://www.egbok.com/hbo.html
riofill (text/plain, 5.5 KB)
#!/usr/bin/perl
#
# riofill - fill a Diamond Rio MP3 player with a randomly selected 
# list of MP3 files.
# Based largely on Ron Forrester's ([email protected]) riolist code.
# which is included in the distribution.
# Hacked upon mercilessly by Howard Owen ([email protected])
# because that's what I do. 8)
#
# perlpod docs at the end
#
use Getopt::Std;

my $VERSION = 1.0;
getopts('d:f:r:ov');
if (!$opt_d){
  $MP3DIR="."; 
} else {
  $MP3DIR=$opt_d;
}
if (defined $opt_r){
  $RIOCMD=$opt_r;
} else {
  $RIOCMD="/usr/local/bin/rio";
}
# We'll test if riocmd is executable after we decide if we want to upload ..

# We'll check the MP3 directory now, however.
die "MP3 directory '$MP3DIR' does not exist or is not a directory" if (! -d $MP3DIR);

#
#  (Modified) truth table for $opt_o and $opt_f options:
#
#  $opt_o    $opt_f                  Action
#  ========================================
#  True      eq "-"                  Output playlist to stdout. Do not upload to Rio
#  True      undef (-f not given)    Output playlist to stdout. Do not upload to Rio
#  True      string other than "-"   Output playlist to $opt_f file. Do not upload to Rio
#  False     Ignored                 Output playlist to tmp file. Upload MP3's to Rio
#
$opt_f= ">".$opt_f if (defined $opt_f); # note that "-f -" results in ">-" = stdout
$opt_f = ">-" if (defined $opt_o && ! defined $opt_f); # implied stdout
$opt_f=">/tmp/playlist.$$" if (! defined $opt_o); # ignore $opt_f

# Now we know if we'll be uploading. Test riocmd
die "$RIOCMD not found or not executable" if (!(defined $opt_o || -x $RIOCMD));

open PL,"$opt_f" || die "Can't open $opt_f  $!";
$STDOUT=select PL; 

print STDERR "Finding MP3 files in $MP3DIR\n" if (defined $opt_v);
@lines = `/usr/bin/find  $MP3DIR -follow -name \\*.mp3 -print`;

# If none found, say so and get out...
#
die "No MP3 files found in $MP3DIR"  if (scalar(@lines) == 0);

# keep track of total size of playlist
#
$totalSize = 0;

#
$maxSize   = (31.5 * 1024 * 1024); # 32 MB doesn't work.
srand( time() ^ ($$ + ($$ << 15)) ); 


# until we are finished...
#
for (;;) {

  last if (! defined ($line= randomSelect(\@lines)));
  chop $line;
  $size=size($line);
  # If adding this one to the list would keep the total size
  # within our limit, then do so.
  #
  if ($totalSize + $size < $maxSize) {
    $totalSize += $size;
    print "$line\n";
  } 
}
close PL;
select $STDOUT;

$opt_f=~s/^>//;
if (! defined $opt_o){ # We're going to upload to the Rio
  if ($opt_v){
    print "$RIOCMD -za\n";
    print `$RIOCMD -za`;
    print "$RIOCMD -v -f $opt_f\n";
    print `$RIOCMD -v -f $opt_f`;
  } else {
    `$RIOCMD -za`;
    `$RIOCMD  -f $opt_f`;
  }
  unlink $opt_f;
}
print "\nriofill done\n";



sub randomSelect {
  # Select and remove a random element from the array 
  # referenced by parameter 
  my ($arRef)=shift;
  if ($#$arRef>=0){ # only if the array is not empty
    return splice @$arRef,int ((rand) * $#$arRef),1;
  } else {
    return undef;
  }
}
sub size {
  my($f)=shift;
  my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size) = stat $f;
  return ($size);
}

=head1 NAME

riofill - make a random playlist from a directory of MP3 files that will fit into a Rio's memory. Optionally upload it to a Rio using SBA's B<rio> utility.

=head1 SYNOPSIS

B<riofill> S<[ B<-ov> ] [ B<-f>I<filename> ] [ B<-d>I<MP3dir> ] [ B<-r>I<riopath> ] >

=head1 DESCRIPTION

The riofill utility randomly selects a list of MP3 files from a given directory.
The utility ensures that the files selected will all fit into the 32MB memory of 
a standard Diamond Rio PMP300. By default, C<riofill> uploads this list to a
Rio PMP 300 connected to the computer's parallel port using the Snowblind Alliance 
(SBA) B<rio> utility. Optionally, the selected playlist may be printed to stdout or 
saved in a file instead of being uploaded to the Rio.

=head2 Switches

Switches include:

=over 5

=item B<-o>

specifies that B<riofill> should output the playlist rather than uploading it to the Rio.
if no B<-f> switch (see below) is given, the playlist is printed to the standard output.
If B<-o> is not given, B<riofill> attempts to upload the generated playlist to a Diamond 
Rio connected to the computer's parallel port.

=item B<-v>

tells B<riofill> to be verbose in its actions. If this switch is given, B<riofill> will
say what it is doing and print the output of the B<rio> utility to standard output.

=item B<-f>I<filename>

specifies a file to which the playlist should be saved. This switch is ignored if B<-o> is not 
given. If B<-o> is given and B<-f> is either not given or equal to "-" B<riofill> prints the playlist
to the standard output.

=item B<-d>I<MP3dir>

specifies the directory in which to look for MP3 files. If B<-d> is not given B<riofill> 
looks for MP3 files in the current directory. B<riofill> searches this directory and any
subdirectories.

=item B<-r>I<riopath>

specifies where the Snowblind Alliance's B<rio> utility is located. If B<-r> is not given, B<riofill>
looks for this utility in /usr/local/bin. If B<riofill> is asked to upload a playlist to the Rio, this
path is checked to ensure the rio utility is present and executable. If it isn't, B<riofill> exits with 
an error message.

=head1 LICENSE

B<riolist> is GPL. B<riofill> is either GPL or Artistic.

=head1 AUTHOR

Based largely on Ron Forrester's E<lt>[email protected]<gt> B<riolist>. His code was hacked upon mercilessly by 
Howard (that's what I do for fun) Owen E<lt>[email protected]<gt> to produce B<riofill>

=head1 SEE ALSO

B<riofill> source, B<riolist> source, rio(1)

=head1 PREREQUISITES

Getopt::Std

=head1 SCRIPT CATEGORIES

Fun/MP3/Rio

=cut
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.