#! /usr/bin/perl
# 
# JF の Berkeley DB ファイルを読んで、リストを出力するための
# スクリプト。
# Fujiwara さんの書いたスクリプトをベースにしている。
#
# -d: 結合する Berkeley DB file の名前
# -t: output format type (HTML or TEXT)
# -c: 出力するカテゴリー名 (省略時はすべて)
# -w: jf.css を参照する HTML を出力 (JF の Web Page 用 INDEX を出力するとき)
# -k: 出力したい文書の KIND (省略時はすべて)
#
use strict;
use vars qw(%opts);
use DB_File;
use jfadmlib qw(:DEFAULT :LOCKS);
use Getopt::Std;
use Time::Local;

getopts('t:d:c:k:w', \%opts);

die unless $opts{'d'};
my $database = $opts{'d'};

my $type = 'TEXT';
$type = $opts{'t'} if $opts{'t'};

my @category = ("install",
		"faq",
		"guide",
		"hardware",
		"diskmanage",
		"filesystem",
		"network",
		"programming",
		"xfree",
		"dtp",
		"database",
		"tool",
		"kernel",
		"etc",
		"archived",
);
@category = $opts{'c'} if $opts{'c'};

my %contrib = (
	       'LILO-doc' => 1,
	       'LTGP'     => 1,
);

my $www = 0;
$www = 1 if $opts{'w'};  

my %kind_description = (
		"all"         => "JFのドキュメントリスト",
		"LDP-TRANS"   => "LDPの翻訳文書一覧",
		"OTHER-TRANS" => "LDP以外の翻訳文書一覧",
		"ORIGINAL"    => "オリジナル文書一覧",
);

my $kind = "all";
$kind = $opts{'k'} if $opts{'k'};
die unless $kind_description{$kind};

my %description = (
		"install"  => "Linuxの紹介とインストール",
		"faq"      => "FAQ",
		"guide"    => "ガイドとチュートリアル",
		"hardware" => "ハードウェアとドライバー",
		"diskmanage" => "ブートとディスク管理",
		"filesystem" => "ファイルシステム",
		"network"  => "ネットワーク",
		"programming" => "プログラミング",
		"xfree"    => "X Window System の設定",
		"dtp"      => "文書作成",
		"database" => "データベース",
		"tool"     => "ツールの解説",
		"kernel"   => "カーネル関連",
		"etc"      => "その他",
		"archived" => "古い文書",
);

#
# get time data
#
my @t = get_timelist(time);

#
# tie database object to hash, and lock it.
#
my ($H, %index);
$H = tie(%index, 'DB_File', $database, O_RDONLY, 0644, $DB_BTREE) or die;

#
# output header
#
if (($type eq "HTML") and ($#category == 0)) {
    print_html_header($www, $description{$category[0]});
    print "<h2 id=\"JFLIST\">$kind_description{$kind}</h2>\n";
} elsif ($type eq "HTML") {
    print_html_header($www, $kind_description{$kind});
    print "<h2 id=\"JFLIST\">$kind_description{$kind}</h2>\n";
} else {
    print "$kind_description{$kind}\n\n";
}

#
# output each datas.
#
foreach my $p (@category) {
    if ($type eq "HTML") {
	print "<h3 id=\"$p\">$description{$p}</h3>\n";
	print "<dl>\n";
    } else {
	print "\n[$description{$p}]\n\n";
    }

    pickup($p, \%index, $H, $type);
    print "</dl>\n" if $type eq "HTML";
}

print_html_footer($www,\@t) if $type eq "HTML";  

#
# untie index.
#
undef $H;
untie %index;
exit;
#
# end of main procedure
#

sub pickup
{
    my ($category, $index, $H, $type) = @_;
    my %jdat_hash;
    my $i = 0;
    foreach my $key (keys %$index) {
	next unless $key =~ /\@\@ITEM$/;
	next unless $index->{$key} =~ /^$category$/;
	my ($name, $dummy) = split("\@\@", $key);

	my $tmpjdat = get_ent($H, $name, "JDAT");
	$tmpjdat = '0' unless $tmpjdat; # dummy
	$tmpjdat .= $i++ if $jdat_hash{$tmpjdat}; # unique key
	$jdat_hash{$tmpjdat} = $name;
    }
    foreach my $key (sort {$b cmp $a;} (keys %jdat_hash)) {
	my $name = $jdat_hash{$key};
	my $CONT = get_ent($H, $name, "CONT");
	my $JDAT = get_ent($H, $name, "JDAT");
	my $TITL = get_ent($H, $name, "TITL");
	my $KIND = get_ent($H, $name, "KIND");
	my (@AUT, @TRN);
	$AUT[0]  = get_ent($H, $name, "AUTH");
	$AUT[1]  = get_ent($H, $name, "AUT2");
	$AUT[2]  = get_ent($H, $name, "AUT3");
	$TRN[0]  = get_ent($H, $name, "TRNS");
	$TRN[1]  = get_ent($H, $name, "TRN2");
	$TRN[2]  = get_ent($H, $name, "TRN3");
	foreach (@AUT, @TRN) {
	    s/<.*>//;
	    s/\s+$//;
	}
	$CONT = "unrecorded" unless $CONT;
	next unless ($kind eq "all") or ($kind eq $KIND);

	my $passed_time;
	if ($JDAT) {
	    my $date = $JDAT;
	    if ($date =~ /^\d+$/) {
		$date = $date . '/01/01';
	    } elsif ($date =~ /^\d+\/\d+$/) {
		$date = $date . '/01';
	    }
	    $date =~ /(\d+)\/(\d+)\/(\d+)/;
	    my ($year, $month, $day) = ($1, $2, $3);
	    $year += 1900 if $year < 1900;
	    $month = 1 if $month == 0;
	    $day = 1 if $day == 0;
	    $passed_time = time - timelocal(0, 0, 0,
					    $day, $month-1, $year-1900);
	} else {
	    $JDAT = "unrecorded";
	    $passed_time = 60*60*24*365; # dummy
	}
	    
	if ($type eq "HTML") {
	    print_html_data($name, $category, $CONT, $JDAT, $TITL, 
			     $KIND, \@AUT, \@TRN, $passed_time);
	} else {
	    print_text_data($name, $category, $CONT, $JDAT, $TITL, 
			    $KIND, \@AUT, \@TRN);
	}
    }
}

sub print_html_data {
    my ($name, $category, $CONT, $JDAT, $TITL, $KIND, $AUT, $TRN, 
	$passed_time) = @_;

    if ($www and $contrib{$KIND}) {
	$name = "../contrib/$KIND/$name";
    } elsif ($contrib{$KIND}) {
	$name = "contrib/$KIND/$name";
    }
    $name = "archive/$name" if $category eq 'archived';

    if (-f "$name.html") {
	print "<dt><a href=\"$name.html\"><strong>$TITL</strong></a>\n";
    } elsif (-d $name) {
	print "<dt><a href=\"$name/\"><strong>$TITL</strong></a>\n";
    } else {
	print "<dt><strong>$TITL</strong>\n";
    }

    print "  <small>($JDAT)</small>";
    if ($passed_time < 60*60*24*31 and $www) { 
	print "\n  <span class=\"new\">new</span>";
    }
    print "</dt>\n";

    print "  <dd>$CONT\n      <small>\n";
    print "      [<a href=\"$name.txt\">テキスト版</a>]\n" if (-f "$name.txt"); 
    print "      <br>\n";
    print "      著者: $AUT->[0]\n" if $AUT->[0];
    print "          , $AUT->[1]\n" if $AUT->[1];
    print "          , $AUT->[2]\n" if $AUT->[2];
    print "      翻訳: $TRN->[0]\n" if $TRN->[0];
    print "          , $TRN->[1]\n" if $TRN->[1];
    print "          , $TRN->[2]\n" if $TRN->[2];
    print "      </small></dd>\n";
}


sub print_text_data {
    my ($name, $category, $CONT, $JDAT, $TITL, $KIND, $AUT, $TRN) = @_;
    $name = "contrib/$KIND/$name" if $contrib{$KIND};
    $name = "archive/$name" if $category eq 'archived';
    my $filename;
    if (-f "$name.txt") {
	$filename = $name . ".txt";
    } elsif (-f "$name.xml") {
	$filename = $name . ".xml";
    } elsif (-f "$name.sgml") {
	$filename = $name . ".sgml";
    } elsif (-d $name) {
	$filename = $name . "/";
    }

    format STDOUT =
 Filename: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Updated: @<<<<<<<<<
           $filename,                                               $JDAT
 Title:    @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
           $TITL
 Description: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<...
           $CONT
.

    write;
    print " Author:   $AUT->[0]"   if $AUT->[0];
    print ", $AUT->[1]"            if $AUT->[1];
    print ", $AUT->[2]"            if $AUT->[2];
    print "\n"                     if $AUT->[0];
    print " Translator: $TRN->[0]" if $TRN->[0];
    print ", $TRN->[1]"            if $TRN->[1];
    print ", $TRN->[2]"            if $TRN->[2];
    print "\n"                     if $TRN->[0];
    print "\n";
}


sub print_html_header {
    my $www = $_[0];
    my $title = $_[1];
    print <<"-HEADER-ONE-";
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja" dir="ltr">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>JF: Index: $title</title>
 <meta name="author" lang="en" content="JF Project Members">
 <meta name="copyright" content="(C) 1998-2011 JF Project.">
 <meta name="description" content="Linux に関する解説文書・FAQ などを作成・収集・配布する JF Project の文書一覧です。">
 <meta name="keywords" content="JF,Linux,Japanese,文書,ドキュメント,翻訳,HOWTO,FAQ">
 <link rev="made" href="mailto:jf\@listserv.linux.or.jp">
-HEADER-ONE-

    print " <link rel=\"stylesheet\" type=\"text/css\" href=\"../jf.css\">\n"
    if $www;
    
    print <<"-HEADER-TWO-";
</head>

<body>

-HEADER-TWO-

    if ($www) {
	print "<h1><a href=\"../index.html\">JF</a>: Index</h1>";
    } else {
	print "<h1>JF-INDEX</h1>";
    }

}

sub print_html_footer {
    my ($www, $t) = @_;
    print <<"-FOOTER-ONE-";
<hr>
 <address>
  JF Project 全般に関わるご意見ご要望は
  jf\@listserv.linux.or.jp までおねがいします。
 </address>
-FOOTER-ONE-

    print <<"-FOOTER-WWW-" if $www;
 <div class="copyright">
  <a href="../index.html">JF Project メインページへ</a><br>
 </div>
-FOOTER-WWW-

 print " <div class=\"copyright\">\n" if $www;
 print "リスト更新日時: $t->[0]/$t->[1]/$t->[2] $t->[4]:$t->[5]:$t->[6]<br>\n";
 print " </div>\n" if $www;
 print "\n</body>\n</html>\n";
}

sub get_timelist() {
  my ($sec,$min,$hour,$day,$month,$year,$wday,$yday,$isdst) = localtime($_[0]);
  my @dow = ("Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat");
  my $dow = $dow[$wday];
  $month = $month + 1;
  $month = 1 if $month == 13;
  $month = "0" . $month if $month < 10;
  $day   = "0" . $day   if $day   < 10;
  $hour  = "0" . $hour  if $hour  < 10;
  $min   = "0" . $min   if $min   < 10;
  $sec   = "0" . $sec   if $sec   < 10;
  $year += 1900;
  return ($year, $month, $day, $dow, $hour, $min, $sec);
}
