#!/usr/bin/perl -w

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
    if 0; # not running under some shell
# $Id: pfifcvt,v 1.9 2005/09/17 22:33:39 ianb Exp $
# Ian Beckwith <ianb@nessie.mcc.ac.uk>
#

use strict;
use XML::PFIF;
use XML::PFIF::Person;
use XML::PFIF::Note;
use XML::PFIF::Reader;

# far too many globals because of callback
use vars qw($me $to_rss $record_count $chunk_record_count
	    $chunk_number $chunk_records $thisfile);
$me=($0=~/(?:.*\/)?(.*)/)[0];
$to_rss=0;
$record_count=0;
$chunk_record_count=0;
$chunk_number="000";
$chunk_records=0;

my $verbose=0;
my $doneargs=0;
my $donesomething=0;
my $title='';
my $description='';
my $link='';

while(($_=shift) && (/^-/) && !$doneargs)
{
    if   (/-o/) { my $arg=shift;
		  if($arg=~/rss/i) { $to_rss=1; } else { $to_rss=0; } }
    elsif(/-t/) { $title=shift;         }
    elsif(/-d/) { $description=shift;   } 
    elsif(/-l/) { $link=shift;          }
    elsif(/-s/) { $chunk_records=shift; }
    elsif(/--/) { $doneargs=1;          }
    elsif(/-h/) { usage();              }
    else { usage(); }
    next;
}

my $infile=$_;
my $outfile=shift || "-";

usage() unless defined($infile);

my $reader=new XML::PFIF::Reader({file=>$infile, callback=>\&do_person});


start_file();


if(!$reader->parse())
{
    warn("$me: $infile: XML parse error\n");
}

end_file();

sub start_file
{
    $thisfile=$outfile;

    if($chunk_records>0)
    {
	$chunk_number++;
	$thisfile .= ".$chunk_number";
    }
    
    open(OUTFILE,">$thisfile") or die("$me: $thisfile: cannot open: $!\n");

    print OUTFILE XML::PFIF::start_xml();

    if($to_rss)
    {
	print OUTFILE XML::PFIF::start_rss();
	print OUTFILE XML::PFIF::start_channel({title=>$title,
					description=>$description,
					lastBuildDate=> XML::PFIF::now(),
					link=>$link});
    }
    else
    {
	print OUTFILE XML::PFIF::start_pfif();
    }
}

sub end_file
{
    if($to_rss)
    {
	print OUTFILE XML::PFIF::end_channel();
	print OUTFILE XML::PFIF::end_rss();
    }
    else
    {
	print OUTFILE XML::PFIF::end_pfif();
    }
    
    close OUTFILE or die "$me: $outfile: Cannot close file: $!\n";
}



sub usage
{
    die("Usage: $me\t[-o xml | rss] [-t title] [-d description] [-l url] \\\n".
	"\t\t[-s records] [-h] [--] infile [outfile]\n".
	" -o xml | rss\tSelect output format (Default: XML)\n".
	" -t title\tTitle of RSS feed\n".
	" -d desc\tDescription of RSS feed\n".
	" -l url\t\tLink associated with RSS feed\n".
	" -s REC\t\tSplit output into files of REC records each, named outfile.1 etc\n".
	" -h\t\tThis help\n".
	" --\t\tEnd of options\n");
}
		
sub do_person
{
    my $person=shift;
    $record_count++;
    $chunk_record_count++;
    if($chunk_records && ($chunk_record_count >= $chunk_records))
    {
	end_file();
	start_file();
	$chunk_record_count=0;
    }
    if($person->is_complete())
    {
	if($to_rss)
	{
	    print OUTFILE $person->to_rss();
	}
	else
	{
	    print OUTFILE  $person->to_xml();
	}
    }
    else
    {
	my $warning="$me: record #$record_count: Incomplete record";
	if($person->person_record_id() ne '')
	{
	    $warning .= ": id: ".$person->person_record_id;
	}
	$warning .="\n";
	warn($warning)
    }
    $person->dispose();
    return 1;
}


__END__


=head1 NAME

pfifcvt - convert PFIF between XML and RSS

=head1 SYNOPSIS

B<pfifcvt> [I<-o xml | rss>] [I<-s records>] [I<-t title>] [I<-d description>] [I<-l link>] [I<-h>] [I<-->] [I<file>]

=head1 DESCRIPTION

Converts between plain PFIF XML and PFIF embedded in RSS. Writes to
standard output if no output file is supplied. With B<-s>, splits
output into multiple files.

=head1 OPTIONS

=over 4

=item B<-o xml | rss>

Choose whether to output plain PFIF XML or PFIF embedded in RSS.
Defaults to plain PFIF XML.

=item B<-s recnum>

Split output into files containing B<recnum> records each.
Files will be named outfile.001, outfile.002, etc    

=item B<-t title>

Value to use for RSS title description element.

=item B<-d description>

Value to use for RSS description element.

=item B<-l link>

Value to use for RSS link element.

=item B<-h>

Show a short help message.

=item B<-->

End of options.

=back

=head1 BUGS

Please report any found to ianb@nessie.mcc.ac.uk	

=head1 SEE ALSO    

L<XML::PFIF>    

=head1 AUTHOR

Ian Beckwith <ianb@nessie.mcc.ac.uk>

=head1 AVAILABILITY

The latest version can be found at:

B<http://nessie.mcc.ac.uk/~ianb/projects/pfif/>

=head1 COPYRIGHT

Copyright 2005 Ian Beckwith <ianb@nessie.mcc.ac.uk>

This code is in the Public Domain.

If you need a license other than Public Domain,
then consider it under the BSD License:

 Copyright (c) Ian Beckwith
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The names of its contributors may not be used to endorse or
    promote products derived from this software without specific prior
    written permission.

 THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.

=cut
