#!/usr/bin/perl -w
###########################################
# magsafe - Archive magazine articles
# Mike Schilli, 2005 (m@perlmeister.com)
###########################################
use strict;

use DBI;
use Class::DBI::Loader;
use Sysadm::Install qw(:all);
use Getopt::Std;
use Text::Iconv;

my $DB_NAME   = "scanned_docs.dat";
my $DSN       = "dbi:SQLite:$DB_NAME";
my $UTF8_TERM = 0;

my $cv = Text::Iconv->new(
                         "Latin1", "utf8");
$cv->raise_error(1);

my $DOC_DIR = "/ms1/DOCS";

getopts("a:m:t:i:p:d:s:", \my %o);

die "$DOC_DIR not ready" if 
    !-d $DOC_DIR or !-w $DOC_DIR;

db_init($DSN) unless -e $DB_NAME;

my $loader = Class::DBI::Loader->new(
   dsn           => $DSN,
   namespace     => "Scanned::DB",
   additional_classes => 
       qw(Class::DBI::AbstractSearch),
   relationships => 1,
);

my $docdb = $loader->find_class("doc");
my $magdb = $loader->find_class("mag");

my @objs = ();

if(! exists $o{s}) {
  my $mag    = mag_pick($magdb, $o{m});
  my $doc    = $o{d} || ask "Document", "";
  my $author = $o{a} || "";
  my $title  = $o{t} || ask "Title", "";
  my $page   = $o{p} || ask "Page", "";
  my $issue  = $o{i} || ask "Issue", "";

  my $id = $mag->add_to_docs({
      map { $UTF8_TERM ? $_ : $cv->convert($_) }
        title  => $title,
        page   => $page,
        issue  => $issue,
        author => $author});

  cp $doc, docpath($id);
  exit 0;
}

my %search = ();

for (split ' ', $o{s}) {

  my($field, $expr) = split /:/, $_;

  if($field eq "mag") {
    my @mags = $magdb->search_like(
                        name => "%$expr%");

    $search{$field} = [
                   map { $_->id() } @mags];
  } else {
    $search{$field} = "%$expr%";
  }
}

@objs = $docdb->search_where(\%search, {cmp => "like"});

if(@objs) {
  print join(", ",
        '"' . $_->title() . '"' ,
        $_->author() || "Unknown",
        $_->mag()->name(),
        $_->issue(), 
        $_->page(),
        docpath($_->docid())),
        "\n" for @objs;
} else {
  print STDERR "No entries\n";
}

###########################################
sub docpath {
###########################################
    my($id) = @_;

    return sprintf "%s/%06d", 
                   $DOC_DIR, $id;
}

###########################################
sub db_init {
###########################################
    my($dsn) = @_;

    my $dbh = DBI->connect($dsn, "", "");

    $dbh->do(q{
        CREATE TABLE doc (
            docid  INTEGER
                   PRIMARY KEY,
            title  VARCHAR(255),
            author VARCHAR(255),
            mag    INT REFERENCES mag,
            page   INT,
            issue  VARCHAR(32)
        );
    });

    $dbh->do(q{
        CREATE TABLE mag (
            magid  INTEGER
                   PRIMARY KEY,
            name   VARCHAR(255)
        )
    });
}

###########################################
sub mag_pick {
###########################################
    my($magsdb, $picked) = @_;

    my @mags = map { $_->name() } 
                   $magsdb->retrieve_all();

    if(@mags and !$picked) {
        $picked = pick "Magazine", 
                       ["New", @mags], 1;
        undef $picked if $picked eq "New";
    }

    if(!$picked) {
      $picked = ask 
                "Enter Magazine Name", "";
    }

    $picked = $UTF8_TERM ? $picked : 
              $cv->convert($picked);

    my $mag = $magsdb->find_or_create(
                       {name => $picked});
    return $mag;
}
