MakeCTTable.pl

#!/usr/local/bin/perl
# (c)copyleft 2022 : Coded by shun kinoshita / knuhs
# 推理法によりカウンター値の一覧表を作成するプログラム
# Make Counter Table V3.1 ( MakeCTTable.pl )
#
# (c) 2000-12-26 By Knuhs(version1)
# (c) 2008-02-03 By Knuhs
# (c) 2013-01-20 By Knuhs
# (c) 2015-11-28 By Knuhs
# (c) 2015-12-04 By Knuhs (version2)
# (c) 2022-01-11 By Knuhs (version3)
# (c) 2022-02-04 By Knuhs (version3.1)
#

     # 【数独】欄のタイトル一覧
my   @sudoku = ("数独ボードのダウンロード", … 略 … );

     # 【素歩人徒然】欄のタイトル一覧
my   @softturezure = (0,"同時通訳", … 略 … );

     # 【ソフトウェア設計論】欄のタイトル一覧
my   @softsekkeiron = (0,"食事マナー", … 略 … );

     # 【近頃腹の立つこと】欄のタイトル一覧
my   @haradachi = (0,"JR駅務員とのやりとり", … 略 … );

     # 【私の作文作法】欄のタイトル一覧
my   @sahou = (0,"「猿でもできる」について", … 略 … );

     # 【ソフトウェアの法則】欄のタイトル一覧
my   @housoku = ("ソフトウェアとペンティアム騒動", … 略 … );

     # 【続・素朴な疑問】欄のタイトル一覧
my   @gimon = (0,"電子メールにサインなど記すのか", … 略 … );

     # 【私の本棚】欄のタイトル一覧
my   @hondana = (0,"手塚治虫ワールドのすべて", … 略 … );

     # 【Perl Programs 集】欄のタイトル一覧
my   @pppro = (0,"AnatomyJPG.pl", … 略 … );

     # 【今だから話そう】欄のタイトル一覧
my   @imadakara = (0,"コワイ先生", … 略 … );

     # カウンターテーブルのグループタイトル
my   %GTitle = ( d => '数独(ナンバープレース)', … 略 … );

     # 【私が耳にした健康情報】欄のタイトル一覧
my   $aref = [ [ '0',  '1',  '2',  '3',  '4',  '5',  '6'  ], … 略 …  ];

my   ($bluei, $redi, $NotCounters) = 0;
my   $nextdate, $lastdate;
my   $date, $timeHM;
my   $countValue, $DateTime;
my   $value, $oldvalue;
my   $flag;

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Program Start here:
#
my   $Test = 0;     # = 1; テスト中( =1 なら核心部のカウンター値は変更しない )

     # カウンター値が置かれている場所
my   $directory = "c:/cdatFile";

     opendir(DIR, "$directory") || die "開けません: $!";
    
     # 各カウンター値を調べる
my   @allfiles = sort grep(/c.*\.dat/, readdir(DIR));

     # 更新開始日時と今回の最後の更新日時とを管理する
     if ( open(DATE, "<$directory/lastupdate") )
     {     $lastdate = <DATE>; close(DATE); }
     else
     {     $lastdate = "1900/01/01";     }
     # 今回の最後の日時が、次の更新開始日時となる
     $nextdate = $lastdate;          

     # カウンターテーブルの先頭部分を作る
     print '<html lang="ja"><head><link rel="shortcut icon" href="../images/knuhs.ico">';
     print '<title>カウンター</title><center><body bgcolor="#001000">';
     print '<style type="text/css">';
     print ' <!--';
     print '  table { font-family:"MS 明朝";';
     print ' font-size:12pt; font-weight:600; }';
     print '  body  { font-family:"MS 明朝";';
     print ' font-size:14pt; }';
     print '  .standard { font-size:14pt; }';
     print '  .title { font-size:18pt; }';
     print '  .subtitle { font-size:16pt; }';
     print '  .note { font-size:11pt; }';
     print '  .note2 { font-size:12pt; }';
     print ' -->';
     print '</style></head>';
     print '<span class="subtitle"><font color="gold"><b>Knuhsの書斎(前回の記録:';
     print "$lastdate)</b></span><br>";
     print '<table border="5" bgcolor="#ffffcc" bordercolor="#ff9900"';
     print ' bordercolorlight="#ff9900" bordercolordark="#993333"><tr>';
     print '<td align="center" bgcolor="#800080" width=350><font color="white">';
     print 'タイトル</font></td><td align="center" bgcolor="#800080">';
     print '<font color="white"><center>Access日時</center></font></td>';
     print '<td align="center" bgcolor="#800080"><font color="white">Access数</font></td>';
     print '<td align="center" bgcolor="#800080"><font color="white">増分</font></td>';
     print '<td align="center" bgcolor="#800080"><font color="white">前回の値</font></td></tr>';

     # カウンターのファイル名を取り出す
     foreach $filename (@allfiles)
     {
          $filename =~ m/c(?!o)(((\w*)|(\.(?=c)))*)\.dat/;
          # 移植に際し2つのモジュールでミスがあり counthp.dat と cf12.count.dat
          # という不要なカウンターが生じてしまった。以下はそれへの対応部分です。
          # (1)counthp.dat を除外するため否定的な前方参照位置指定子(?!o)を用いている。
          # この場合、$1,$2,... の位置番号は変わらない点に注意。
          # (2)cf12.count.dat を除外するため肯定的な前方参照位置指定子(?=c)も用いている。
          # 本来であれば     m/c(\w+)\.dat/; で良いはず。

          # 表示するカウンターの区分けのためのグループタイトル(GTitle)を表示する
          # cd,dat, cf.dat, ch,dat, ck.dat, cm.dat, cn.dat, cp.dat,
          # cr.dat, cs.dat, ct.dat, cx.dat 等々
          if( length($1) == 1 )
          {    # GTitle行(紫色"#800080")を挿入
               print '<tr><td bgcolor="#800080" width="350"><font color="white">▼';
               print " <b>$GTitle{$1}</font></b></td>";
               print '<td bgcolor="#800080"> </td><td bgcolor="#800080"> </td>';
               print '<td bgcolor="#800080"> </td><td bgcolor="#800080"> </td></tr>';
               next;     # next文の飛び先は goto skip; と同じ(see skip:)
          }
          
          # 新しい行を作る
          print '<tr><td>'; print "(c$1)"; $NotCounters++;

          # 「タイトル」欄を作る
          # 規則性のないものは個々にタイトルを記入する
          if($1 eq "shunhp2")
          {    print "<font color=red>Knuhsの書斎(2)(…/index.htm)</font>";   }
          elsif($1 eq "shunhp")
          {    print "<font color=red>旧・Knuhsの書斎入口(3)(main.htm)</font>";   }
          elsif($1 eq "rootTop")
          {    print "<font color=red>Knuhsの書斎(1)(…/index.html)</font>";   }
          elsif($1 eq "skhp")
          {    print "<font color=red>Knuhsの書斎(4)</font>";   }
          elsif($1 eq "shtop")
          {    print "<font color=red>Knuhsの書斎(サイトマップ)</font>";   }
          elsif($1 eq "reader")
          {    print "<font color=red>メンバ登録欄(2008-4-1閉鎖)</font>";   }
          elsif($1 eq "heart")
          {    print "<font color=red>円からハートへ</font>";   }
          elsif($1 eq "spade")
          {    print "<font color=red>スペード曲線</font>";   }
          elsif($1 eq "n01")
          {    print "<font color=red>悪魔の辞典</font>";}
          elsif($1 eq "jigazou")
          {    print "<font color=red>自画像欄</font>";}
          elsif($1 eq "jibunNow")
          {    print "<font color=red>私め近影</font>";}
          elsif($1 eq "suudoku")
          {    print "<font color=red>数独欄の案内</font>";}
          elsif($1 eq "meibo")
          {    print "<font color=green>松涛名簿欄</font>";}
          elsif($1 eq "syoutou")
          {    print "<font color=green>松涛ホームページ</font>";}
          elsif($1 eq "toyama")
          {    print "<font color=green>戸山高校クラス会</font>";}
          elsif($1 eq "present")
          {    print "<font color=blue>秘密のページ</font>";}
          elsif($1 eq "happyou")
          {    print '<font color=blue>プレゼント発表</font>';}
          elsif($1 eq "hayashi")
          {    print '<font color=blue>林ゼミOB会</font>';}
          elsif($1 eq "kika")
          {    print '<font color=blue>幾何の問題正解集</font>';}
          elsif($1 eq "kikb")
          {    print '<font color=blue>幾何の問題正解集公開</font>';}
          elsif($1 eq "lock")
          {   print '<font color=blue>カラークロック</font>';}
          elsif($1 eq "x01")
          { print '<font color=blue>旧サイトマップ</font>';}
          elsif($1 eq "x02")
          {    print '<font color=blue>新サイトマップ</font>';}
          elsif($1 eq "x03")
          {    print '<font color=blue>戸山33関係サイトマップ</font>';}
          elsif($1 eq "x04")
          {    print '<font color=blue>松涛4関係サイトマップ</font>';}
          elsif($1 eq "x05")
          {    print '<font color=blue>砧小27関係サイトマップ</font>';}
          elsif($1 eq "x06")
          {    print '<font color=blue>My Computer Career</font>';}
          elsif($1 eq "x07")
          {    print '<font color=blue>TOSHIBA Computers</font>';}
          elsif($1 eq "x08")
          {    print '<font color=blue>Perl Program集</font>';}
          elsif($1 eq "x09")
          {    print '<font color=blue>私の本棚</font>';}
          elsif($1 eq "x091")
          {    print '<font color=blue>“今だから話そう”掲示履歴</font>';}
          elsif($1 eq "x10")
          {    print '<font color=blue>*** 全アクセス表 ***</font>';}
          elsif($1 eq "x11")
          {    print '<font color=blue>私の作ったPerlプログラム</font>';}
          elsif($1 eq "x12")
          {    print '<font color=blue>新版・私が耳にした健康情報(2)</font>';}
          elsif($1 eq "x13")
          {    print '<font color=blue>旧版・私が耳にした健康情報(1)</font>';}
          elsif($1 eq "spam.count")
          {    print '<font color=blue>自己アドレス迷惑メール撃退法(2)</font>';}
          elsif($1 eq "spam")
          {    print '<font color=blue>自己アドレス迷惑メール撃退法</font>';}
          elsif($1 eq "tani")
          {    print '<font color=blue>10進/2進・度量衡表現</font>';}
          else
          {    # 規則性のあるものはタイトル集から選んで記入する
               $filename =~ /c([d,f,g,h,i,k,m,p,r,s,t])(.*)\.dat/;
               if($1 eq "d")   {  print $sudoku[$2];  }
               elsif($1 eq "f"){  print $hondana[$2];  }
               elsif($1 eq "g"){  print $gimon[$2];  }
               elsif($1 eq "h"){  print $housoku[$2-35];  }
               elsif($1 eq "i"){  print $imadakara[$2];  }
               elsif($1 eq "k")  # 健康情報のみは2段構えの構造
               { my $i = $2 / 10; my $j = $2 % 10;
                 if( $j == 1 )
                 { print ":<font color=\"blue\">\<b\>${${$aref}[$i]}[0]\</b\>\</font\>\<br\>    ";  }
                 print ":${${$aref}[$i]}[$j]";
               }
               elsif($1 eq "m"){  print $sahou[$2];  }
               elsif($1 eq "p"){  print 'Perl:',$pppro[$2];  }
               elsif($1 eq "r"){  print $haradachi[$2];  }
               elsif($1 eq "s"){  print $softsekkeiron[$2];  }
               elsif($1 eq "t"){  print $softturezure[$2];  }
          }
          print '</td><td>';   # タイトル欄を閉じる

          # 「Access日時」欄を作る
          open(IN, "<$directory/$filename");
          $value = <IN>;

          # 日時(Date と Time)情報を取り出す
          $value =~ m/([\d]*)\$(\d{4}\/\d{2}\/\d{2})[\s|:](\d\d:\d\d).*/;
          $countValue = $1;
          $date = $2;
          $timeHM = $3;

          $flag = 0;  # カウンター値が変更されたかを記憶する(変更されると=1)
          if ($date ge $lastdate)
          {    if ($date eq $lastdate)
               {    # 青色で日時を表記し前回変更されたものを示す
                    print '<font color=blue><b>', $date, ' ', $timeHM, '</b></font>';
                    $bluei++; $flag=1;  # 前回変更されたものの総数をカウント
               }
               else
               {    if($date gt $nextdate){ $nextdate = $date; }
                    # 赤色で日時を表記し今回変更されたものを示す
                    print '<font color=red><b>', $date, ' ', $timeHM, '</b></font>';
                    $redi++; $flag=1;  # 今回変更されたものの総数をカウント
               }
          }
          else
          {    print $date, ' ', $timeHM;  }   # 変更なしのものの日時を表記

          # 「Access日時」欄を閉じ、「Access数」欄を作る
          print '</td><td><center>';
          print "$countValue", '</center></td>';

          # 前回の値を取り出す
          open(IN, "<c:/cdatFile/cdatFile-data/$filename");
          $oldvalue = <IN>;
    
          $oldvalue =~ m/(\d*)\$?(.*)/;
          $oldvalue = $1;
          close(IN);

          # 今回の値と前回の値との差を求め、差があれば「増分」欄に記入する
          my $diff = $countValue - $oldvalue;
          print '</td><td><center>';
          print '+',"$diff" if $diff;
          print '</center></td>';

          # 変更があったものは /cdatFile-data に保存
          if ( $flag == 1 )
          {    open(OUT, ">c:/cdatFile/cdatFile-data/$filename");
               printf OUT "$countValue\n" unless $Test;   # Test のときは書き込まない
               close(OUT);
          }

          # 「前回の値」欄を作り表示する
          print '<td bgcolor="#ccff00"><center>', "$oldvalue", '</center></td>';
          print '</tr>',"\n";   # 1行分を完結する

skip:  # next; の飛び先
     } # End of foreach $filename (@allfiles)

     # カウンターの一覧表を閉じる
     print '</table><b>';

     # 一覧の下部にまとめの情報を表記する
     print "Update($nextdate)", "<font color=\"red\">$redi</font>";
     print '+',"<font color=\"#87ceeb\">$bluei</font>";
     print '=', $redi+$bluei ,"か所参照されました。\n";
     print "<br><IMG SRC=\"images/red.gif\">総カウンター数 = $NotCounters\n";
     print '</b></center></html>';
     print "<br><center><IMG SRC=\"images/green.gif\">カウンター:";
     print "<img src=\"http://cgi01.itscom.net/cgi-bin/Count.cgi?df=";
     print "f1003240.cx10.dat|dd=A|comma=Y|st=324|sh=Y|\"></center><br>";
     print '</b></center></html>';

     # 次回に備えての情報管理
     open(DATE, ">$directory/lastupdate");
     printf(DATE $nextdate) unless $Test;   # Test のときは書き込まない
     close(DATE);
     closedir(DIR);
     exit;

__END__