#!/usr/local/bin/perl
##--------------------------------------------------------------------------##
##  File:
##      $Id: mh-month-pack,v 1.2 2002/07/09 01:25:21 ehood Exp $
##  Description:
##      See POD below or run program with -man option.
##--------------------------------------------------------------------------##
##  Copyright (C) 2002	    Earl Hood <earl@earlhood.com>
##
##  This program is free software; you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation; either version 2 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program; if not, write to the Free Software
##  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
##  02111-1307, USA
##--------------------------------------------------------------------------##

package MHArc::mh_month_pack;

use Pod::Usage;
use Getopt::Long;

use constant SCAN_FORMAT_STR =>
    '%(msg) %<{x-mharc-packed}*%>%(year{date})-%02(mon{date})-%02(mday{date})';

my $debug = 0;
my $verbose = 0;
my $noop = 0;
my $noanno = 0;
my $all = 0;

my $outdir = '.';
my $yearly = 0;

MAIN: {
  # Grap command-line options
  GetOptions(
    "all!"        => \$all,
    "debug!"      => \$debug,
    "n!"          => \$noop,
    "noanno!"     => \$noanno,
    "outdir=s"	  => \$outdir,
    "verbose!"    => \$verbose,
    "yearly!"     => \$yearly,

    "help"        => \$help,
    "man"         => \$man
  ) || usage(0);
  usage(1) if $help;
  usage(2) if $man;

  $verbose = 1  if $noop;
  $verbose = 1  if $debug;

  my @folders = @ARGV;
  if (@folders <= 0) {
    die qq/Error: No folders specified\n/;
  }

  # Trim in leading +'s specified
  foreach (@folders) {
    s/^\+//;
  }

  # Save off current folder
  my $curfolder = `folder -fast`;
  chomp $curfolder;
  print qq/Current folder is "$curfolder"\n"/  if $verbose;

  local(*SCAN);
  my $folder;
  foreach $folder (@folders) {
    print qq/Processing folder "$folder"...\n/  if $verbose;

    # Open read pipe to scan to get message number and date for each
    # message.
    if (!open(SCAN, qq/scan +$folder -format '/.SCAN_FORMAT_STR.qq/'|/)) {
      warn qq/Warning: Non-zero exit status from "scan": $?\n/;
      next;
    }

    my($msg, $date, $rest);
    my($year, $mon, $day);
    my($mbox, $packed);

    # Read scan output and copy messages into mailbox files
    while (<SCAN>) {
      next  unless /^\s*\d/;

      print $_  if $debug;
      chomp;

      ($msg, $date, $rest) = split(' ', $_, 3);
      $packed = $date =~ s/\*//;

      if (!$all && $packed) {
	print qq/Skipping message "$msg", already packed.\n/;
	next;
      }

      $date += 1900  if $date < 1900;	# just incase
      ($year, $mon, $day) = split('-', $date, 3);

      if ($yearly) {
	$mbox = $year;
      } else {
	$mbox = "$year-$mon";
      }

      # Pre-create the mbox file if it does not exist: prevents
      # packf from prompting to create.
      if (! -e $mbox) {
	run_cmd("touch $outdir/$mbox");
      }

      # Have packf actually append message to mailbox file.
      if (run_cmd("packf -mbox -file $outdir/$mbox $msg")) {
	warn qq/Warning: Non-zero exit status from "packf": $?\n/;
	next;
      }

      # Annotate message that it has been processed.
      if (!$noanno) {
	if (run_cmd("anno -component x-mharc-packed -inplace -nodate ".
		    "-text '1' $msg")) {
	  warn qq/Warning: Non-zero exit status from "anno": $?\n/;
	  next;
	}
      }
    }

    close(SCAN);
  }

  # Restore current folder
  run_cmd("folder +$curfolder");

} # End: MAIN


sub run_cmd {
  if ($verbose) {
    print @_, "\n";
  }
  return 0  if ($noop);
  system(@_);
}

sub usage {
  require Pod::Usage;
  my $verbose = shift;
  if ($verbose == 0) {
    Pod::Usage::pod2usage(-verbose => $verbose);
  } else {
    my $pager = $ENV{'PAGER'} || 'more';
    local(*PAGER);
    my $fh = (-t STDOUT && open(PAGER, "|$pager")) ? \*PAGER : \*STDOUT;
    Pod::Usage::pod2usage(-verbose => $verbose,
			  -output  => $fh);
  }
}


##--------------------------------------------------------------------------##
__END__

=head1 NAME

mh-month-pack - Copy MH/nmh messages into monthly mailbox files.

=head1 SYNOPSIS

  mh-month-pack [options] folder ...

=head1 DESCRIPTION

This program copies MH/nmh messages into mailbox files.  By default,
monthly mailbox files are created with filenames of I<YYYY-MM> format.
If the C<-yearly> option is specified, than messages will be split
into yearly, I<YYYY>, files.  If a mailbox file already exists,
messages will be appended to it.

Each MH/nmh process will be annotated inorder to mark it that
it has been processed by this program, unless the C<-noanno> option
is specified.  The annotation allows this program to reprocess folders
multiple times and to skip messages that have been packed before.

This program is provided as part of MHArc to provide the ability to
import MH/nmh messages into MHArc archives.  This program could be
used for sites that have an existing MH/nmh filtering system inplace
and want to usage MHArc to generate web-based archives.  This program
can be used instead of C<filter-spool> to move incoming messages into
the raw message archive before calling C<web-archive>.

=head1 OPTIONS

=over

=item C<-all>

Force packing of all messages, if even if message is marked as
already have been processed.

=item C<-debug>

Like C<-verbose>, but prints out more.

=item C<-help>

Print out help message.

=item C<-man>

Print out the manpage.

=item C<-n>

Just echo what would be done, but do not do it.

=item C<-noanno>

Do not annotate message that it has been packed.  By default, this
program will annotate the message via the anno(1) command to mark
the message that it has been processed.  Therefore, if the folder
is processed again in the future, the message will be skipped.

=item C<-outdir> I<directory>

Directory to place mailbox files.  If not specified, the
current working directory is used.

=item C<-verbose>

Print status of what is going on.

=item C<-yearly>

Generate yearly-based mailbox files instead of monthly-based.

=back

=head1 DEPENDENCIES

This program requires that the following MH/nmh commands are in
your search path: anno(1), folder(1), scan(1), packf(1).

=head1 LIMITATIONS

=over

=item *

Pre-existing gzipped mailbox files are not recognized.

=back

=head1 VERSION

$Id: mh-month-pack,v 1.2 2002/07/09 01:25:21 ehood Exp $

=head1 AUTHOR

Earl Hood, earl@earlhood.com

This program is part of the MHArc archiving system and comes with
ABSOLUTELY NO WARRANTY and may be copied only under the terms of
the GNU General Public License, which may be found in the MHArc
distribution.

=cut

