ホーム > WWWページ作成について > AWStatsの改造

AWStatsの改造


2018.7.18 高橋 誠

 AWStats7.0の日本語化がAWStats Ver.7.0 完全日本語版に公開されていますが、2018年1月に7.7がリリースされました。これを若干修正して動作させたので報告します。

目次

AWStats 7.0日本語のダウンロードと確認

 AWStats Ver.7.0 完全日本語版からダウンロードして指示どおりにして動作しました。当サイトのログから参照いただけます。

Perlパッケージの追加

HTML::Entities::Numbered
 レコード中の文字参照の解析のため追加。
Unicode::Japanese
 CP932の変換のため。
Jcode
 日本語コードの変換のため。
 CPANを使いました。
tmp>perl -MCPAN -e shell

色々と質問に答えます。

CPAN>install HTML::Entities::Numbered
CPAN>install Unicode::Japanese
CPAN>install Jcode

HTML 4.01にあうように修正

 とりあえず、実際の動作上は問題ないのですが、Another HTML-lintに怒られるソースが気持ち悪いので、下記の修正をしました。
<br />をなくす。
 XHTMLとHTMLの両方の出力形式をサポートしているのですが、タグがXHTMLにのみ対応しているようです。次の変更で変数化し、/ \/>/$endtag/で全文置換しました。
 widthの変数化を拡張しました。
--- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/awstats.pl  2018-01-07 15:36:46.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/awstats.pl    2018-02-22 09:53:28.246222900 +0900
@@ -46,9 +49,10 @@
 use vars qw/
   $DEBUGFORCED $NBOFLINESFORBENCHMARK $FRAMEWIDTH $NBOFLASTUPDATELOOKUPTOSAVE
   $LIMITFLUSH $NEWDAYVISITTIMEOUT $VISITTIMEOUT $NOTSORTEDRECORDTOLERANCE
-  $WIDTHCOLICON $TOOLTIPON
+  $WIDTHCOLICON $WIDTHHIT $WIDTHPAGE $WIDTHBANDWIDTH $WIDTHFULLDATE $WIDTHPARCENT $WIDTHYESNO $WIDTHBROWSER $WIDTHOS $TOOLTIPON
   $lastyearbeforeupdate $lastmonthbeforeupdate $lastdaybeforeupdate $lasthourbeforeupdate $lastdatebeforeupdate
+  $endtag $OptionSelect
   $NOHTML
 /;
 $DEBUGFORCED=0
   ; # Force debug level to log lesser level into debug.log file (Keep this value to 0)
@@ -62,8 +66,17 @@
 $NOTSORTEDRECORDTOLERANCE = 20000
   ; # Lapse of time to accept a record if not in correct order. 20000 = 2 hour (Default = 20000)
 $WIDTHCOLICON = 32;
+$WIDTHHIT     = 70;
+$WIDTHPAGE    = 70;
+$WIDTHBANDWIDTH = 80;
+$WIDTHFULLDATE = 160;
+$WIDTHPARCENT = 80;
+$WIDTHYESNO   = 50;
+$WIDTHBROWSER = 130;
+$WIDTHOS      = 140;
 $TOOLTIPON    = 0;    # Tooltips plugin loaded
 $NOHTML       = 0;    # Suppress the html headers
+$endtag = ">";        # Set HTML 4.01

 # ----- Running variables -----
 use vars qw/
option要素のselected属性
 HTML 4.01では、<option selected>
XHTML 1.1では、<option selected="selected">としなければならないので、上記で同じく変数化しました。
@@ -2701,6 +2735,13 @@
        if ( $BuildReportFormat !~ /html|xhtml|xml/i ) {
                $BuildReportFormat = 'html';
        }
+       if ($BuildReportFormat eq "html") {     # HTML 4.1
+               $endtag=">";
+               $OptionSelect = "selected";
+       } else {                                # XHTML 1.1
+               $endtag=" />";
+               $OptionSelect = "selected=\"selected\"";
+       }
        if ( $BuildHistoryFormat !~ /text|xml/ ) { $BuildHistoryFormat = 'text'; }
        if ( $SaveDatabaseFilesWithPermissionsForEveryone !~ /[0-1]/ ) {
                $SaveDatabaseFilesWithPermissionsForEveryone = 0;
言語コードをjaに
jpは、国コードで言語コードはjaです。他にも国コードと言語コードが混在していたので、言語コードに統一しました。これに合わせ、langモジュールの名前も変更しています。XHTML 1.1の正式版がでているのでXHTML 1.1にしました。
@@ -416,62 +434,81 @@
 # HTTP-Accept or Lang parameter => AWStats code to use for lang
 # ISO-639-1 or 2 or other       => awstats-xx.txt where xx is ISO-639-1
 %LangBrowserToLangAwstats = (
-   'sq'    => 'al',
    'ar'    => 'ar',
    'ba'    => 'ba',
+   'be'    => 'be',
    'bg'    => 'bg',
-   'zh-tw' => 'tw',
-   'zh'    => 'cn',
-   'cs'    => 'cz',
+   'ca'    => 'ca',
+   'cs'    => 'cs',
+   'cy'    => 'cy',
+   'da'    => 'da',
    'de'    => 'de',
-   'da'    => 'dk',
+   'el'    => 'el',
    'en'    => 'en',
+   'es'    => 'es',
    'et'    => 'et',
+   'eu'    => 'eu',
    'fi'    => 'fi',
    'fr'    => 'fr',
    'gl'    => 'gl',
-   'es'    => 'es',
-   'eu'    => 'eu',
-   'ca'    => 'ca',
-   'el'    => 'gr',
+   'he'    => 'he',
+   'hr'    => 'hr',
    'hu'    => 'hu',
+   'id'    => 'id',
    'is'    => 'is',
-   'in'    => 'id',
    'it'    => 'it',
-   'ja'    => 'jp',
-   'kr'    => 'ko',
+   'ja'    => 'ja',
+   'ko'    => 'ko',
+   'lt'    => 'lt',
    'lv'    => 'lv',
-   'nl'    => 'nl',
-   'no'    => 'nb',
    'nb'    => 'nb',
+   'nl'    => 'nl',
    'nn'    => 'nn',
+   'no'    => 'nb',
    'pl'    => 'pl',
    'pt'    => 'pt',
-   'pt-br' => 'br',
+   'pt-br' => 'pt-br',
    'ro'    => 'ro',
    'ru'    => 'ru',
-   'sr'    => 'sr',
    'sk'    => 'sk',
-   'sv'    => 'se',
+   'sq'    => 'sq',
+   'sr'    => 'sr',
+   'sv'    => 'sv',
    'th'    => 'th',
    'tr'    => 'tr',
-   'uk'    => 'ua',
-   'cy'    => 'cy',
-   'wlk'   => 'cy'
+   'uk'    => 'uk',
+   'zh'    => 'zh',
+   'zh-tw' => 'zh-tw'
 );
 %LangAWStatsToFlagAwstats =
   (  # If flag (country ISO-3166 two letters) is not same than AWStats Lang code
+   'ar' => 'sa',
    'ca' => 'es_cat',
+   'cs'    => 'cz',
+   'cy' => 'gb_wls',
+   'da'    => 'dk',
+   'el'    => 'gr',
    'et' => 'ee',
    'eu' => 'es_eu',
-   'cy' => 'wlk',
-   'gl' => 'glg',
+   'gl' => 'es_ga',
    'he' => 'il',
+   'ja'    => 'jp',
    'ko' => 'kr',
-   'ar' => 'sa',
-   'sr' => 'cs'
+   'pt-br' => 'br',
+   'sq'    => 'al',
+   'sr' => 'cs',
+   'sv' => 'se',
+   'uk'    => 'ua',
+   'zh'    => 'cn',
+   'zh-tw' => 'tw'

@@ -808,21 +869,17 @@
                print "<?xml version=\"1.0\" encoding=\"$PageCode\"?>\n";
            }
            else { print "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"; }
-           if ( $FrameName ne 'index' ) {
+#          if ( $FrameName ne 'index' ) {
                print
-"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n";
-           }
-           else {
-               print
-"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n";
-           }
+"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n";
+#          }
            print
 "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"$Lang\">\n";
        }
        else {
            if ( $FrameName ne 'index' ) {
                print
-"<!DOCTYPE html \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n";
+"<!DOCTYPE html \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
            }
            else {
                print
bgcolorは薦められない属性です
スタイルシートに変更しました。また、valign属性も薦められない属性なのでスタイルシートにしました。また、オリジナルはスタイルシートによらず、見場を変えていたので実際の見場にあうようにスタイルシートを調整しました。
--- /cygdrive/c/awstats-7.7-mod/wwwroot/css/awstats_bw.css  2014-09-23 08:16:08.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/css/awstats_bw.css    2013-08-06 15:42:32.540785000 +0900
@@ -1,21 +1,24 @@
 body { font: 11px verdana, arial, helvetica, sans-serif; background-color: #FFFFFF; margin-top: 0 }
 .aws_bodyl { }
 .aws_border { background-color: #BBBBBB; padding: 1px 1px 1px 1px; margin-top: 0 }
-.aws_title  { font: 13px verdana, arial, helvetica, sans-serif; font-weight: bold; background-color: #BBBBBB; text-align: center; margin-bottom: 0; padding: 1px 1px 1px 1px; }
+.aws_title  { font: 13px verdana, arial, helvetica, sans-serif; font-weight: bold; background-color: #CCCCDD; text-align: center; margin: 1em 30% -1em 0; padding: 1px 1px 1px 1px; }
 .aws_blank { font: 13px verdana, arial, helvetica, sans-serif; background-color: #FFFFFF; text-align: center; margin-bottom: 0; padding: 1px 1px 1px 1px; }
 .aws_data {
    background-color: #FFFFFF;
    border-top-width: 1px;
-   border-left-width: 0px;
-   border-right-width: 0px;
-   border-bottom-width: 0px;
+   border-left-width: 1px;
+   border-right-width: 1px;
+   border-bottom-width: 1px;
+   border-color: #CCCCDD;
+   border-style:outset;
+   margin-top:1em;
 }
-.aws_formfield { font: 13px verdana, arial, helvetica; }
+.aws_formfield { font: 13px verdana, arial, helvetica, sans-serif; }
 .aws_button {
    font-family: arial,verdana,helvetica, sans-serif;
    font-size: 12px;
    border: 1px solid #ccd7e0;
-   background-image: url(/awstatsicons/other/button.gif);
+   background-image: url(/awstats/icon/other/button.gif);
 }
 th         { border-color: #ECECEC; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 0px; padding: 2px 2px 2px 2px; font: 11px verdana, arial, helvetica, sans-serif; text-align:center; color: #000000; }
 th.aws     { border-color: #ECECEC; border-left-width: 0px; border-right-width: 1px; border-top-width: 0px; border-bottom-width: 0px; padding: 2px 2px 2px 2px; font-size: 13px; font-weight: bold; }
@@ -24,8 +27,30 @@
 td.awsm    { border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; padding: 0px 0px 0px 0px; font: 11px verdana, arial, helvetica, sans-serif; color: #000000; }
 b { font-weight: bold; }
 a { font: 11px verdana, arial, helvetica, sans-serif; }
-a:link    { color: #001133; text-decoration: none; }
-a:visited { color: #001133; text-decoration: none; }
-a:hover   { color: #444444; text-decoration: underline; }
-div { font: 12px arial,verdana,helvetica; text-align:justify; }
-.ctooltip { position:absolute; top:0px; left:0px; z-index:2; width:380; visibility:hidden; font: 8pt MS Comic Sans,arial,sans-serif; background-color: #EEEEEE; padding: 8px; border: 1px solid black; }
\ No newline at end of file
+a:link    { color: #0011BB; text-decoration: none; }
+a:visited { color: #0011BB; text-decoration: none; }
+a:hover   { color: #605040; text-decoration: underline; }
+div { font: 12px arial,verdana,helvetica,sans-serif; text-align:justify; }
+.ctooltip { position:absolute; top:0px; left:0px; z-index:2; width:380px; visibility:hidden; font: 8pt "MS Comic", Sans,arial,sans-serif; background-color: #EEEEEE; padding: 8px; border: 1px solid black; }
+img {border-width: 0em}
+.vmiddle {vertical-align:middle;}
+table {table-layout:fixed}
+.currentday { font-weight: bold; }
+.colortab  { background-color: #ECECEC}
+.colore  { background-color: #CEC2E8}
+.colorh  { background-color: #66DDEE}
+.colork  { background-color: #2EA495}
+.colorp  { background-color: #4477DD}
+.colors  { background-color: #8888DD}
+.coloru  { background-color: #FFAA66}
+.colorv  { background-color: #F4F090}
+.colorweekend  { background-color: #EAEAEA}
+.colorx  { background-color: #C1B2E2}
+.colorBGTitle  { background-color: #CCCCDD}
+.colorOSfamily  { background-color: #F6F6F6}
+.bottom {vertical-align:bottom;}
+.nowrap  { white-space:nowrap}
+tleft {text-align:left}
+tright {text-align:right}
+.aws_horizontal_graph {line-height:0px; text-align:left;}
二重のテーブルにするよりcaptionにすべきでしょう
@@ -1053,32 +1071,22 @@

    if ( $width == 70 && $QueryString =~ /buildpdf/i ) {
        print
-"<table class=\"aws_border\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"800\">\n";
+"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"796\" summary=\"$title1\" id=\"$class\">\n";
    }
    else {
        print
-"<table class=\"aws_border\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n";
+"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\" summary=\"$title1\" id=\"$class\">\n";
    }

    if ($tooltipnb) {
-       print "<tr><td class=\"aws_title\" width=\"$width%\""
+       print "<caption class=\"aws_title\""
          . Tooltip($tooltipnb,$tooltipnb)
-         . ">$title "
-         . $extra_head_html . "</td>";
-   }
-   else {
-       print "<tr><td class=\"aws_title\" width=\"$width%\">$title "
-         . $extra_head_html . "</td>";
-   }
-   print "<td class=\"aws_blank\"></td></tr>\n";
-   print "<tr><td colspan=\"2\">\n";
-   if ( $width == 70 && $QueryString =~ /buildpdf/i ) {
-       print
-"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"796\">\n";
+         . ">$title"
+         . $extra_head_html . "</caption>\n";
    }
    else {
-       print
-"<table class=\"aws_data\" border=\"1\" cellpadding=\"2\" cellspacing=\"0\" width=\"100%\">\n";
+       print "<caption class=\"aws_title\">$title"
+         . $extra_head_html . "</caption>\n";
    }
 }

&、>、<のエスケープ
 XHTMLの場合のみエスケープしているのですが、HTML 4.01でも必要です。
@@ -7831,10 +7867,15 @@
 # Return:      encodedstring
 #------------------------------------------------------------------------------
 sub XMLEncode {
-   if ( $BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml' ) {
-       return shift;
-   }
+# エスケープはHTMLでも必要
+#  if ( $BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml' ) {
+#      return shift;
+#  }
    my $string = shift;
+   $string =~ s/&lt;/</g;  # to avoid &lt; bocome &amp;lt; if after CleanXSS
+   $string =~ s/&gt;/>/g;  # to avoid &lt; bocome &amp;gt; if after CleanXSS
+   $string =~ s/&quot;/"/g;    # to avoid &lt; bocome &amp;quot; if after CleanXSS
+   $string =~ s/&apos;/'/g;    # to avoid &lt; bocome &amp;apos; if after CleanXSS
    $string =~ s/&/&amp;/g;
    $string =~ s/</&lt;/g;
    $string =~ s/>/&gt;/g;
@@ -7853,8 +7894,16 @@
 sub XMLEncodeForHisto {
    my $string = shift;
    $string =~ s/\s/%20/g;
+   $string =~ s/&lt;/</g;
+   $string =~ s/&gt;/>/g;
+   $string =~ s/&quot;/"/g;
+   $string =~ s/&apos;/'/g;
    if ( $BuildHistoryFormat ne 'xml' ) { return $string; }
    $string =~ s/=/%3d/g;
+   $string =~ s/&lt;/</g;
+   $string =~ s/&gt;/>/g;
+   $string =~ s/&quot;/"/g;
+   $string =~ s/&apos;/'/g;
    $string =~ s/&/&amp;/g;
    $string =~ s/</&lt;/g;
    $string =~ s/>/&gt;/g;
target属性は薦められない属性です
 フレームも使えません。target="xxx"を一括削除しました。
imgにはheight属性とwidth属性を指定しましょう。imgにはalt属性が必要です。
@@ -8088,9 +8169,9 @@
            );
            print "<a href=\""
              . XMLEncode("$AWScript${NewLinkParams}lang=$lng")
-             . "\"$NewLinkTarget><img src=\"$DirIcons\/flags\/$flag.png\" height=\"14\" border=\"0\""
+             . "\"$NewLinkTarget><img src=\"$DirIcons\/flags\/$flag.png\" height=\"14\" width=\"14\""
              . AltTitle("$lngtitle")
              . "$endtag</a>&nbsp;\n";
        }
@@ -9917,22 +10051,35 @@
            }
            else {
                print
-"<tr><td class=\"aws\" valign=\"middle\"><strong>$Message[7]:</strong>&nbsp;</td><td class=\"aws\" valign=\"middle\"><span style=\"font-size: 14px;\">$SiteDomain</span></td>";
+"<tr><td class=\"aws vmiddle\"><strong>$Message[7]:</strong></td><td class=\"aws vmiddle\"><span style=\"font-size: 14px;\">$SiteDomain</span></td>";
            }

            # Logo and flags
+           my $width;
+           my $height;
+           if ($Logo eq "awstats_logo1.png") {
+               $width = 111;
+               $height = 51;
+           } elsif  ($Logo eq "awstats_logo5.png") {
+               $width = 230;
+               $height = 54;
+           } elsif  ($Logo eq "awstats_logo6.png") {
+               $width = 112;
+               $height = 54;
+           }
            if ( $FrameName ne 'mainleft' ) {
                if ( $LogoLink =~ "http://www.awstats.org" ) {
                    print "<td class=\"tright\" rowspan=\"3\"><a href=\""
                      . XMLEncode($LogoLink)
-                     . "\"><img src=\"$DirIcons/other/$Logo\" border=\"0\""
+                     . "\"><img src=\"$DirIcons/other/$Logo\" width=\"$width\" height=\"$height\""
                      . AltTitle( ucfirst($PROG) . " Web Site" )
                      . "$endtag</a>";
                }
                else {
                    print "<td align=\"right\" rowspan=\"3\"><a href=\""
                      . XMLEncode($LogoLink)
-                     . "\" target=\"awstatshome\"><img src=\"$DirIcons/other/$Logo\" border=\"0\"$endtag</a>";
+                     . "\"><img src=\"$DirIcons/other/$Logo\" width=\"$width\" height=\"$height\""
+                     . AltTitle(ucfirst($PROG)." Web Site")."$endtag</a>";
                }
                if ( !$StaticLinks ) { print "<br$endtag"; Show_Flag_Links($Lang); }
                print "</td>";
tdのheight属性とwidth属性は薦められない属性です
col要素に指定してみました。
@@ -12514,7 +12863,14 @@
                $cpt = ( scalar keys %_host_h );
            }
            &tab_head( "$title", 19, 0, 'hosts' );
-           print "<tr bgcolor=\"#$color_TableBGRowTitle\"><th>";
+       print "<col$endtag";
+       &ShowHostInfo('__col__');
+       if ($ShowHostsStats =~ /P/i) { print "<col width=\"$WIDTHPAGE\"$endtag";}
+       if ($ShowHostsStats =~ /H/i) { print "<col width=\"$WIDTHHIT\"$endtag";}
+       if ($ShowHostsStats =~ /B/i) { print "<col width=\"$WIDTHBANDWIDTH\"$endtag";}
+       if ($ShowHostsStats =~ /L/i) { print "<col width=\"$WIDTHFULLDATE\"$endtag";}
+       print "\n";
+           print "<tr class=\"colortab\"><th abbr=\"$Message[79]\">";
            if ( $FilterIn{'host'} || $FilterEx{'host'} ) {    # With filter
                if ( $FilterIn{'host'} ) {
                    print "$Message[79] '<strong>$FilterIn{'host'}</strong>'";
td内に空白文字しかありません
 <td>&nbsp;</td>を<td></td>に一括変換しました。
<b>は物理的フォントタグです。論理的タグを使うようにしましょう
 <b>, </b>を<strong>, </strong>に一括変換しました。

XHTML 1.1にあうように変更

Javascriptファイルの分離
XHTMLではコメントアウトで逃げられませんから、別ファイルにしました。定義も追加しました。
--- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/awstats.pl  2018-01-07 15:36:46.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/awstats.pl    2018-02-22 09:53:28.246222900 +0900
@@ -308,7 +324,7 @@
   )
   = ( 2, 2, 0, 2, 2, 2, 2, 2, 2 );
 use vars qw/
-  $DirLock $DirCgi $DirConfig $DirData $DirIcons $DirLang $AWScript $ArchiveFileName
+  $DirLock $DirCgi $DirConfig $DirData $DirIcons $DirJs $DirCss $DirLang $AWScript $ArchiveFileName
   $AllowAccessFromWebToFollowingIPAddresses $HTMLHeadSection $HTMLEndSection $LinksToWhoIs $LinksToIPWhoIs
   $LogFile $LogType $LogFormat $LogSeparator $Logo $LogoLink $StyleSheet $WrapperScript $SiteDomain
   $UseHTTPSLinkForUrl $URLQuerySeparators $URLWithAnchor $ErrorMessages $ShowFlagLinks
@@ -318,6 +334,7 @@
 (
    $DirLock,                                  $DirCgi,
    $DirConfig,                                $DirData,
    $DirIcons,                                 $DirLang,
+   $DirJs,                                    $DirCss,                     # JS, CSS 用ディレクトリ
    $AWScript,                                 $ArchiveFileName,
    $AllowAccessFromWebToFollowingIPAddresses, $HTMLHeadSection,
    $HTMLEndSection,                           $LinksToWhoIs,
@@ -1958,6 +1974,14 @@
            if ( $QueryString !~ /diricons=([^\s&]+)/i ) { $DirIcons = $value; }
            next;
        }
+       if ($param =~ /^DirJs/) {
+           if ($QueryString !~ /dirjs=([^\s&]+)/i) { $DirJs=$value; }
+           next;
+           }
+       if ($param =~ /^DirCss/) {
+           if ($QueryString !~ /dircss=([^\s&]+)/i) { $DirCss=$value; }
+           next;
+           }
        if ( $param =~ /^SiteDomain/ ) {

            # No regex test as SiteDomain is always exact value
@@ -2667,6 +2692,9 @@
    $DirData      ||= '.';
    $DirCgi       ||= '/cgi-bin';
    $DirIcons     ||= '/icon';
+   $DirJs        ||= '/js';
+   $DirCss       ||= '/css';
+   $StyleSheet   ||= '$DirCss/awstats_bw.css';
    if ( $DNSLookup !~ /[0-2]/ ) {
        error(
 "DNSLookup parameter is wrong in config/domain file. Value is '$DNSLookup' (should be 0,1 or 2)"
--- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/plugins/tooltips.pm 2016-08-27 19:59:00.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/plugins/tooltips.pm   2014-03-14 14:24:13.712726400 +0900
@@ -103,50 +103,17 @@
                        $doctop="document.documentElement.scrollTop";
                }

-               print <<EOF;
-
-<script language="javascript" type="text/javascript">
-function ShowTip(fArg)
-{
-       var tooltipOBJ = (document.getElementById) ? document.getElementById('tt' + fArg) : eval("document.all['tt" + fArg + "']");
-       if (tooltipOBJ != null) {
-               var tooltipLft = ($docwidth?$docwidth:document.body.style.pixelWidth) - (tooltipOBJ.offsetWidth?tooltipOBJ.offsetWidth:(tooltipOBJ.style.pixelWidth?tooltipOBJ.style.pixelWidth:$TOOLTIPWIDTH)) - 30;
-               var tooltipTop = 10;
-               if (navigator.appName == 'Netscape') {
-                       tooltipTop = ($doctop>=0?$doctop+10:event.clientY+10);
-                       tooltipOBJ.style.top = tooltipTop+"px";
-                       tooltipOBJ.style.left = tooltipLft+"px";
-               }
-               else {
-                       tooltipTop = ($doctop>=0?$doctop+10:event.clientY+10);
-                       tooltipTop = (document.body.scrollTop>=0?document.body.scrollTop+10:event.clientY+10);
-EOF
                # Seul IE en HTML a besoin de code supplémentaire. IE en xhtml est OK
                if ($BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml') {
 print <<EOF;
-                       if ((event.clientX > tooltipLft) && (event.clientY < (tooltipOBJ.scrollHeight?tooltipOBJ.scrollHeight:tooltipOBJ.style.pixelHeight) + 10)) {
-                               tooltipTop = ($doctop?$doctop:document.body.offsetTop) + event.clientY + 20;
-               }
+<script language="javascript" type="text/javascript" src="$DirJs/tooltiph.js"></script>
 EOF
-               }
+               } else {
 print <<EOF;
-                       tooltipOBJ.style.left = tooltipLft;
-                       tooltipOBJ.style.top = tooltipTop;
-               }
-               tooltipOBJ.style.visibility = "visible";
-       }
-}
-function HideTip(fArg)
-{
-       var tooltipOBJ = (document.getElementById) ? document.getElementById('tt' + fArg) : eval("document.all['tt" + fArg + "']");
-       if (tooltipOBJ != null) {
-               tooltipOBJ.style.visibility = "hidden";
-       }
-}
-</script>
+<script language="javascript" type="text/javascript" src="$DirJs/tooltipx.js"></script>

 EOF
-
+               }
        }
        return 1;
        # ----->
@@ -198,6 +165,7 @@
                        s/#RobotArray#/$aws_NbOfRobots/;
                        s/#WormsArray#/$aws_NbOfWorms/;
                        s/#SearchEnginesArray#/$aws_NbOfSearchEngines/;
+                       s/#br#/<br$endtag/;
                        print "$_";
                }
        }
XHTMLのContent-typeはapplication/xhtml+xmlです
 XHTMLの場合、相手によってtext/htmlにしていましたが、スタティックなxhtmlを生成する場合もあるので、潔く諦めました。IEの古いバージョンを使う場合は、HTML指定にしてください。
@@ -767,10 +831,7 @@
    if ( !$HeaderHTTPSent ) {
        my $newpagecode = $PageCode ? $PageCode : "utf-8";
        if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
-           print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i
-                  ? "Content-type:text/html; charset=$newpagecode\n"
-                  : "Content-type: text/xml; charset=$newpagecode\n"
-           );
+           print "Content-type: application/xhtml+xml; charset=$newpagecode\n" );
        }
        else { print "Content-type: text/html; charset=$newpagecode\n"; }
Content-typeがapplication/xhtml+xmlの場合meta http-equivの指定をすべきではありません。
 http-equiv="description"でなく、name="description"に訂正しました。keywordsも同様。
@@ -852,19 +909,12 @@
                          . "follow\"$endtag\n";
        }
        else {
-           print "<meta name=\"robots\" content=\"noindex,nofollow\"$endtag\n";
+           print "<meta name=\"robots\" content=\"NOINDEX,NOFOLLOW\"$endtag\n";
        }

        # Affiche tag meta content-type
        if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
-           print( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i
-               ? "<meta http-equiv=\"content-type\" content=\"text/html; charset="
-                 . ( $PageCode ? $PageCode : "iso-8859-1" )
-                 . "\"$endtag\n"
-               : "<meta http-equiv=\"content-type\" content=\"text/xml; charset="
-                 . ( $PageCode ? $PageCode : "iso-8859-1" )
-                 . "\"$endtag\n"
-           );
+           ;
        }
        else {
            print
@@ -874,83 +924,43 @@
        }

        if ($Expires) {
+           if ( $BuildReportFormat ne 'xhtml' && $BuildReportFormat ne 'xml' ) {
            print "<meta http-equiv=\"expires\" content=\""
              . ( gmtime( $starttime + $Expires ) )
              . "\"$endtag\n";
        }
+       }
        my @k = keys
          %HTMLOutput;    # This is to have a unique title and description page
-       print "<meta http-equiv=\"description\" content=\""
+       print "<meta name=\"description\" content=\""
          . ucfirst($PROG)
          . " - Advanced Web Statistics for $SiteDomain$periodtitle"
          . ( $k[0] ? " - " . $k[0] : "" )
          . "\"$endtag\n";
-       if ( $MetaRobot && $FrameName ne 'mainleft' ) {
+       if ( $FrameName ne 'mainleft' ) {
            print
-"<meta http-equiv=\"keywords\" content=\"$SiteDomain, free, advanced, realtime, web, server, logfile, log, analyzer, analysis, statistics, stats, perl, analyse, performance, hits, visits\"$endtag\n";
+"<meta name=\"keywords\" content=\"$SiteDomain, free, advanced, realtime, web, server, logfile, log, analyzer, analysis, statistics, stats, perl, analyse, performance, hits, visits\"$endtag\n";
        }
        print "<title>$Message[7] $SiteDomain$periodtitle"
          . ( $k[0] ? " - " . $k[0] : "" )
          . "</title>\n";
        if ( $FrameName ne 'index' ) {

-           if ($StyleSheet) {
-               print "<link rel=\"stylesheet\" href=\"$StyleSheet\"$endtag\n";
+           if ($TOOLTIPON) {
+               if ( $BuildReportFormat eq 'xhtml' || $BuildReportFormat eq 'xml' ) {
+                   if ( $ENV{'HTTP_USER_AGENT'} =~ /MSIE|Googlebot/i ){
+                       print "<meta http-equiv=\"Content-Script-Type\" content=\"text/javascript\"$endtag\n";
            }
XHTMLではformにname属性を指定できません
また、指定値は全部大文字にしました。
@@ -8752,54 +8852,56 @@
        $NewLinkParams =~ s/^&amp;//;
        $NewLinkParams =~ s/&amp;$//;
        if ($NewLinkParams) { $NewLinkParams = "${NewLinkParams}&amp;"; }
-       print "\n<form name=\"FormFilter\" action=\""
+       print "\n<form"
+         . ($BuildReportFormat eq 'html' ? " name=\"FORMFILTER\"" : "")
+         . " id=\"FORMFILTER\" action=\""
          . XMLEncode("$AWScript?${NewLinkParams}")
          . "\" class=\"aws_border\">\n";
        print
@@ -9886,22 +10017,25 @@
            if ( $FrameName eq 'mainright' ) {
                $NewLinkTarget = "";
            }
-           print "<form name=\"FormDateFilter\" action=\""
+           print "<form"
+             . ($BuildReportFormat eq 'html' ? " name=\"FORMDATEFILTER\"" : "")
+             . " id=\"FORMDATEFILTER\" action=\""
              . XMLEncode("$AWScript?${NewLinkParams}")
              . "\" style=\"padding: 0px 0px 0px 0px; margin-top: 0\">\n";
        }

CSS 2.0にあうように変更

一般的なフォント名称
フォントの羅列の最後には一般的なフォント名称を入れておくことが推奨されています。
--- /cygdrive/c/awstats-7.7-mod/wwwroot/css/awstats_bw.css  2014-09-23 08:16:08.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/css/awstats_bw.css    2013-08-06 15:42:32.540785000 +0900
@@ -1,21 +1,24 @@
 body { font: 11px verdana, arial, helvetica, sans-serif; background-color: #FFFFFF; margin-top: 0 }
 .aws_bodyl { }
 .aws_border { background-color: #BBBBBB; padding: 1px 1px 1px 1px; margin-top: 0 }
-.aws_title  { font: 13px verdana, arial, helvetica, sans-serif; font-weight: bold; background-color: #BBBBBB; text-align: center; margin-bottom: 0; padding: 1px 1px 1px 1px; }
+.aws_title  { font: 13px verdana, arial, helvetica, sans-serif; font-weight: bold; background-color: #CCCCDD; text-align: center; margin: 0 0 0 0; padding: 1px 1px 1px 1px; }
 .aws_blank { font: 13px verdana, arial, helvetica, sans-serif; background-color: #FFFFFF; text-align: center; margin-bottom: 0; padding: 1px 1px 1px 1px; }
 .aws_data {
    background-color: #FFFFFF;
    border-top-width: 1px;
-   border-left-width: 0px;
-   border-right-width: 0px;
-   border-bottom-width: 0px;
+   border-left-width: 1px;
+   border-right-width: 1px;
+   border-bottom-width: 1px;
+   border-color: #CCCCDD;
+   border-style:outset;
+   margin-top:1em;
 }
-.aws_formfield { font: 13px verdana, arial, helvetica; }
+.aws_formfield { font: 13px verdana, arial, helvetica, sans-serif; }
 .aws_button {
        font-family: arial,verdana,helvetica, sans-serif;
        font-size: 12px;
    border: 1px solid #ccd7e0;
-   background-image: url(/awstatsicons/other/button.gif);
+   background-image: url(/awstats/icon/other/button.gif);

ブラウザの追加

携帯、RSSリーダ等を追加
KDDI、goo RSS Reader等。

ロボットの追加

検索に来たロボットを追加
検索が来ていたので入れてみました。

サーチエンジンの追加

参照してくれたサーチエンジンを追加しました。
参照してくれたサーチエンジンを追加しました。

検索語、検索文のUTF-8化

utf8_decode.plで、UTF-8に変換してしまった検索語、検索文と%等でエスケープされた検索語、検索文が同じものだと認識されなかったので、履歴ファイル格納時にUTF-8にするように統一しました。また、半角英数字、全角カタカナに統一しました。
@@ -7901,8 +7950,40 @@
    my $stringtodecode = shift;
    $stringtodecode =~ tr/\+/ /s;
    $stringtodecode =~ s/%([A-F0-9][A-F0-9])/pack("C", hex($1))/ieg;
-   $stringtodecode =~ s/["']//g;
-
+   if ( $stringtodecode =~ /&.+;/ ) {
+       $stringtodecode = HTML::Entities::Numbered::name2hex($stringtodecode);
+       while ($stringtodecode =~ /(&#x([0-9a-fA-F]{4});)/) {
+           my $a = $1;
+           my $b = pack("H*","FEFF".$2);           # EncodeはBOMを要求する。
+           Encode::from_to($b, "utf16", "utf8");
+           $stringtodecode =~ s/$a/$b/;
+       }
+       while ($stringtodecode =~ /(&#x([0-9a-fA-F]{2});)/) {
+           $a = $1;
+           $b = pack("H*","FEFF00".$2);            # EncodeはBOMを要求する。
+           Encode::from_to($b, "utf16", "utf8");
+           $stringtodecode =~ s/$a/$b/;
+       }
+       while ($stringtodecode =~ /(&#([0-9]+);)/) {
+           $a = $1;
+           $b = sprintf "%X", $2;
+           if ( length($b) == 3 ) {
+               $b = "0" . $b;
+           } elsif ( length($b) == 2 ) {
+               $b = "00" . $b;
+           } elsif ( length($b) == 1 ) {
+               $b = "000" . $b;
+           }
+           $b = pack("H*","FEFF".$b);          # EncodeはBOMを要求する。
+           Encode::from_to($b, "utf16", "utf8");
+           $stringtodecode =~ s/$a/$b/;
+       }
+   }
+   $stringtodecode = Unicode::Japanese->new($stringtodecode)->h2zKana->get;
+   $stringtodecode = Unicode::Japanese->new($stringtodecode)->z2hSym->get;
+   $stringtodecode = Unicode::Japanese->new($stringtodecode)->z2hNum->get;
+   $stringtodecode = Unicode::Japanese->new($stringtodecode)->z2hAlpha->get;
+   $stringtodecode = $KeyWordsNotSensitive ? lc( $stringtodecode ) : $stringtodecode;
    return $stringtodecode;
 }

utf8_decode.plの改造

日付の様式等の日本語化

@@ -739,7 +776,34 @@
    'Konqueror versions'
    ',',
    'Downloads',
-   'Export CSV'
+   'Export CSV',
+   '','','','','','','','','','',
+   '','','','','','','','','','',
+   'dd mmm yyyy',
+   'mmmbreakyyyy',
+   'mmm yyyy',
+   'ddbreakmmm',
+   "Unknown robot (identified by '",
+   "')",
+   "Common *nix tool for automating web document retireval. Most likely a bot.",
+   "Suspected Bot masquerading as Motorola",
+   "Suspected bot masqurading as Mozilla",
+   "Unknown robot (identified by empty user agent string)",
+   "Unknown robot (identified by hit on 'robots.txt')",
+   "Often spam bot",
+   "Unknown or unspecified distribution",
+   "unknown version",
+   "Unknown Unix system",
+   'Unknown search engines',
+   "Suspected bot masquerading as MS IE",
+   "Generic bot identified as '1', '2' or '3'",
+   "",
+   "",
+   "",
+   "Entries shown here gave hits or traffic \"not viewed\" by visitors, so they are included only in \"Not viewed traffic\" chart of Summary.",
+   "yyyy",
+   "Year yyyy",
+   "Month mmm yyyy"
  );

 #------------------------------------------------------------------------------
@@ -8173,13 +8254,19 @@
 }

 #------------------------------------------------------------------------------
-# Function:        Format a date according to Message[78] (country date format)
+# Function:        Format a date according to messages (country date format)
 # Parameters:   String date YYYYMMDDHHMMSS
-#               Option 0=LastUpdate and LastTime date
-#                      1=Arrays date except daymonthvalues
-#                      2=daymonthvalues date (only year month and day)
-# Input:        $Message[78]
-# Output:       None
+#               Option 0=LastUpdate and LastTime date $Message[78]
+#                      1=Arrays date except daymonthvalues $Message[78]
+#                      2=daymonthvalues date (only year month and day) $Message[200]
+#                      3=mmm
yyyy (2 line date) $Message[201] +# 4=mmm yyyy (only year and month) $Message[202] +# 5=dd mmm (only day and month) $Message[203] +# 6=yyyy (only year) $Message[222] +# 7=Year yyyy $Message[223] +# 8=Month yyyy mmm $Message[224] +# Input: $date +# Output: $dateformat # Return: Date with format defined by Message[78] and option #------------------------------------------------------------------------------ sub Format_Date { @@ -8193,18 +8280,31 @@ my $sec = substr( "$date", 12, 2 ); my $dateformat = $Message[78]; + $day =~ s/^0//; #supress leading 0 + if ( $option == 2 ) { - $dateformat =~ s/^[^ymd]+//g; - $dateformat =~ s/[^ymd]+$//g; + $dateformat = $Message[200]; # dd mmm yy + } elsif ($option == 3) { # mmm<br>yyyy + $dateformat = $Message[201]; + } elsif ($option == 4) { # mmm yyyy + $dateformat = $Message[202]; + } elsif ($option == 5) { # dd<br>mmm + $dateformat = $Message[203]; + } elsif ($option == 6) { # yyyy + $dateformat = $Message[222]; + } elsif ($option == 7) { # Year yyyy + $dateformat = $Message[223]; + } elsif ($option == 8) { # Month yyyy mmm + $dateformat = $Message[224]; } $dateformat =~ s/yyyy/$year/g; $dateformat =~ s/yy/$year/g; $dateformat =~ s/mmm/$MonthNumLib{$month}/g; - $dateformat =~ s/mm/$month/g; $dateformat =~ s/dd/$day/g; $dateformat =~ s/HH/$hour/g; $dateformat =~ s/MM/$min/g; $dateformat =~ s/SS/$sec/g; + $dateformat =~ s/break/<br$endtag/g; return "$dateformat"; } @@ -12975,27 +13344,28 @@ if ( $LogType eq 'W' || $LogType eq 'S' ) { $w = '17'; $colspan = 6; + print "<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag\n"; + } else { + print "<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag<col width=\"$w%\"$endtag\n"; } # Show first/last - print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; + print "<tr class=\"colortab\">"; print "<td class=\"aws\"><strong>$Message[133]</strong></td><td class=\"aws\" colspan=\"" . ( $colspan - 1 ) . "\">\n"; print( $MonthRequired eq 'all' - ? "$Message[6] $YearRequired" - : "$Message[5] " - . $MonthNumLib{$MonthRequired} - . " $YearRequired" + ? Format_Date("$YearRequired"."00000000000",7) + : Format_Date("$YearRequired$MonthRequired"."00000000",8) ); print "</td></tr>\n"; - print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; + print "<tr class=\"colortab\">"; print "<td class=\"aws\"><strong>$Message[8]</strong></td>\n"; print "<td class=\"aws\" colspan=\"" . ( $colspan - 1 ) . "\">" . ( $FirstTime ? Format_Date( $FirstTime, 0 ) : "NA" ) . "</td>"; print "</tr>\n"; - print "<tr bgcolor=\"#$color_TableBGRowTitle\">"; + print "<tr class=\"colortab\">"; print "<td class=\"aws\"><strong>$Message[9]</strong></td>\n"; print "<td class=\"aws\" colspan=\"" . ( $colspan - 1 ) . "\">" @@ -13230,9 +13600,14 @@ { my @blocklabel = (); for ( my $ix = 1 ; $ix <= 12 ; $ix++ ) { + my $bold = + ( $ix == $nowmonth + && $YearRequired == $nowyear ? ':' : '' ); my $monthix = sprintf( "%02s", $ix ); + my $labeltmp = Format_Date( "$YearRequired$monthix"."00000000", 3 ); + $labeltmp =~ s/<br$endtag/#br#/; push @blocklabel, - "$MonthNumLib{$monthix}\n$YearRequired"; + "$labeltmp$bold"; } my @vallabel = ( "$Message[11]", "$Message[10]", @@ -13389,7 +13765,7 @@ ? '<span class="currentday">' : '' ); - print "$MonthNumLib{$monthix}<br$endtag$YearRequired"; + print Format_Date("$YearRequired$monthix"."00000000",3); print( !$StaticLinks && $monthix == $nowmonth && $YearRequired == $nowyear ? '</span>' : '' ); @@ -13452,7 +13835,7 @@ ? '<span class="currentday">' : '' ); - print "$MonthNumLib{$monthix} $YearRequired"; + print Format_Date("$YearRequired$monthix"."00000000",4); print( !$StaticLinks && $monthix == $nowmonth && $YearRequired == $nowyear ? '</span>' : '' ); @@ -13627,8 +14010,10 @@ && $year == $nowyear ? ':' : '' ); my $weekend = ( DayOfWeek( $day, $month, $year ) =~ /[06]/ ? '!' : '' ); + my $labeltmp = Format_Date( "$year$month$day"."00000000", 5 ); + $labeltmp =~ s/<br$endtag/#br#/; push @blocklabel, - "$day\n$MonthNumLib{$month}$weekend$bold"; + "$labeltmp$weekend$bold"; } my @vallabel = ( "$Message[10]", "$Message[56]", @@ -13816,30 +14201,31 @@ ? '<span class="currentday">' : '' ); - print "$day<br$endtag<span style=\"font-size: " - . ( $FrameName ne 'mainright' - && $QueryString !~ /buildpdf/i ? "9" : "8" ) - . "px;\">" - . $MonthNumLib{$month} - . "</span>"; + print Format_Date("$year$month$day"."000000",5); print( !$StaticLinks && $day == $nowday && $month == $nowmonth && $year == $nowyear ? '</span>' : '' ); print "</td>\n"; } - print "<td></td>"; +# print "<td></td>"; print "<td class=\"vmiddle\"" . Tooltip(18) . ">$Message[96]</td>\n"; print "</tr>\n"; print "</table>\n"; } - print "<br$endtag\n"; +# print "<br$endtag\n"; # Show data array for days if ($AddDataArrayShowDaysOfMonthStats) { - print "<table>\n"; + print "<table summary=\"Show data array for days\" style=\"margin-left:auto;margin-right:auto\">\n"; + print "<col width=\"$WIDTHFULLDATE\"$endtag"; + if ($ShowDaysOfMonthStats =~ /V/i) { print "<col width=\"$WIDTHHIT\"$endtag";} + if ($ShowDaysOfMonthStats =~ /P/i) { print "<col width=\"$WIDTHPAGE\"$endtag";} + if ($ShowDaysOfMonthStats =~ /H/i) { print "<col width=\"$WIDTHHIT\"$endtag";} + if ($ShowDaysOfMonthStats =~ /B/i) { print "<col width=\"$WIDTHBANDWIDTH\"$endtag";} + print "\n"; print "<tr><td class=\"colortab\">$Message[4]</td>"; if ( $ShowDaysOfMonthStats =~ /V/i ) { --- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/lang/awstats-en.txt 2018-03-13 14:13:33.267036600 +0900 +++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/lang/awstats-en.txt 2014-03-14 11:42:58.467770200 +0900 @@ -180,3 +181,49 @@ message176=Konqueror versions message177=, message178=Downloads +message179= +message180= +message181= +message182= +message183= +message184= +message185= +message186= +message187= +message188= +message189= +message190= +message191= +message192= +message193= +message194= +message195= +message196= +message197= +message198= +message199= +message200=dd mmm yyyy +message201=mmmbreakyyyy +message202=mmm yyyy +message203=ddbreakmmm +message204=Unknown robot (identified by ' +message205=') +message206=Common *nix tool for automating web document retireval. Most likely a bot. +message207=Suspected Bot masquerading as Motorola +message208=Suspected bot masqurading as Mozilla +message209=Unknown robot (identified by empty user agent string) +message210=Unknown robot (identified by hit on 'robots.txt') +message211=Often spam bot +message212=Unknown or unspecified distribution +message213=unknown version +message214=Unknown Unix system +message215=Unknown search engines +message216=Suspected bot masquerading as M$ IE +message217=Generic bot identified as '1', '2' or '3' +message218=Your browser does not support Java correctly. Change browser or disable AWStats graphapplet plugin. +message219= +message220= +message221=Entries shown here gave hits or traffic "not viewed" by visitors, so they are included only in "Not viewed traffic" chart of Summary. +message222=yyyy +message223=Year yyyy +message224=Month mmm yyyy --- /cygdrive/c/awstats-7.2-mod/wwwroot/classes/src/AWGraphApplet.java 2004-01-08 00:32:04.000000000 +0900 +++ /cygdrive/c/AWStats72t_jpn/wwwroot/classes/src/AWGraphApplet.java 2011-02-03 14:33:58.629627500 +0900 @@ -186,6 +187,7 @@ if (i!=-1) { //System.out.println("i = " + i); sub = s.substring(iOld+1, i); + i = i + c.length() - 1; } else { sub = s.substring(iOld+1, s.length()); bFin=true; @@ -351,7 +353,7 @@ if (blabels[j].indexOf("!")>0) { highlight=1; label=remove(blabels[j],"!"); } if (bold==1) { g.setFont(fontb); } - String as[] = split(label, "\247", 0); + String as[] = split(label, "#br#", 0); // Write background for block legend if (highlight==1) { g.setColor(special_color); --- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/lang/awstats-ja.txt 2018-01-07 15:15:24.000000000 +0900 +++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/lang/awstats-ja.txt 2014-03-14 11:46:22.578170200 +0900 @@ -1,66 +1,68 @@ # Japanese message file (info@kchosting.jp) # $Revision: 1.9 $ - $Date: 2004/06/07 19:04:36 $ +# Modified by Ryu 2004.07.20 +# Modified by makoto_hobbit 2010.12.17 PageCode=UTF-8 message0=不明 -message1=不明(ipが解りません) +message1=名前解決ができないホスト message2=その他 -message3=詳細を見る +message3=詳細の閲覧 message4=日 -message5=月 -message6=年 -message7=統計 +message5=月次 +message6=年次 +message7=統計対象サイト message8=最初の訪問 message9=最後の訪問 -message10=訪問数 -message11=訪問者 +message10=訪問回数 +message11=一意な訪問者数 message12=訪問 -message13=キーワード -message14=検索 -message15=パーセント +message13=種類の検索語 +message14=検索回数 +message15=割合 message16=容量 message17=ドメイン/国名 message18=訪問者 -message19=URLページ -message20=時間 +message19=ページ数/URL +message20=時間帯 message21=ブラウザ -message22=HTTPエラー -message23=参照 +message22= +message23=参照元 message24=更新なし -message25=訪問者・ドメイン/国名 +message25=訪問者のドメイン/国名 message26=ホスト message27=ページ -message28=ページ -message29=アクセス -message30=他の言葉 -message31=ページが見つかりません -message32=HTTPエラーコード -message33=Netscapeバージョン -message34=IEバージョン -message35=最終の更新 -message36=このサイトへのアクセス元 -message37=アクセス元 -message38=直接URLを入力/お気に入りからのアクセス -message39=起点が不明 -message40=インターネット検索エンジンからのリンク -message41=外部ページからのリンク(検索エンジンを除く他のホームページ) -message42=内部ページからのリンク(同じサイトの他のページ) -message43=検索エンジンの文字列(キーフレーズ) -message44=検索エンジンの文字列(キーワード) -message45=不明なIPアドレス -message46=不明なOS(参照フィールド) -message47=要求されたURLは見つかりません(HTTPコード404) -message48=未解決のIPアドレス -message49=エラー 件数 -message50=不明ブラウザ(参照フィールド) -message51=ロボットの訪問 +message28=種類のページ +message29=閲覧 +message30=上記以外の検索語 +message31=見つからなかったページ +message32=HTTPステータスコード +message33=Netscapeのバージョン +message34=Internet Explorerのバージョン +message35=最後の更新 +message36=このサイトへの接続元 +message37=接続元 +message38=直接URLを入力/ブックマーク/e-mailのリンク +message39=不明な接続元 +message40=検索エンジンからのリンク +message41=外部ページからのリンク(検索エンジンを除くWebサイト) +message42=内部ページからのリンク(同一サイトの他のページ) +message43=検索エンジンで利用された検索文 +message44=検索エンジンで利用された検索語 +message45=名前解決できないIPアドレス +message46=不明なOS(UserAgentフィールド) +message47=要求されたが存在しなかったURL(HTTPコード404) +message48=IPアドレス +message49=エラー ヒット +message50=不明なブラウザ(UserAgentフィールド) +message51=種類のロボット message52=訪問/訪問者 message53=ロボット/スパイダーの訪問者 -message54=上級web統計のフリーリアルタイムログファイル分析 -message55=の +message54=一歩進んだアクセス解析を可能にするフリーなリアルタイムログ解析スクリプト +message55=(日本語では不要) message56=ページ -message57=件数 +message57=ヒット message58=バージョン -message59=オペレーティングシステム +message59=OS message60=1月 message61=2月 message62=3月 @@ -73,17 +75,17 @@ message69=10月 message70=11月 message71=12月 -message72=ナビゲーション +message72=アクセス状況 message73=ファイルの種類 -message74=更新する -message75=バイト +message74=今すぐ更新 +message75=帯域 message76=メインページに戻る -message77=トップ -message78= yyyy年 mmm dd日 - HH:MM -message79=フィルター +message77=上位 +message78=yyyy年mmmdd日 - HH:MM +message79=フィルタ message80=全リスト -message81=ホスト -message82=既知 +message81=ホスト名 +message82=既知のホスト message83=ロボット message84=日曜日 message85=月曜日 @@ -93,79 +95,136 @@ message89=金曜日 message90=土曜日 message91=曜日 -message92=だれ -message93=いつ -message94=認証されたユーザー +message92=訪問者の属性 +message93=訪問日時 +message94=認証されたユーザ message95=最小 message96=平均 message97=最大 -message98=Web圧縮 -message99=帯域幅の保存 +message98=mod_zipによる圧縮 +message99=節約されたバイト数 message100=圧縮前 message101=圧縮後 message102=合計 -message103=キーフレーズ -message104=入り口 +message103=種類の検索文 +message104=最初に閲覧 message105=コード -message106=平均サイズ +message106=平均データ長 message107=ニュースグループからのリンク -message108=Kb -message109=Mb -message110=Gb +message108=kB +message109=MB +message110=GB message111=Grabber message112=Yes message113=No -message114=WhoIs情報 +message114=WhoIsDBの情報 message115=OK -message116=出口 -message117=訪問の長さ -message118=ウィンドーを閉じる -message119=バイト -message120=検索文字列(キーフレーズ) -message121=検索文字列(キーワード) -message122=検索エンジン -message123=ホームページ -message124=他のフレーズ -message125=他のログイン -message126=検索エンジン -message127=ホームページ -message128=サマリー -message129=「年」ビューでは精密な数字はありません +message116=最後に閲覧 +message117=滞在時間 +message118=このウィンドウを閉じる +message119=B +message120=検索文 +message121=検索語 +message122=の検索エンジンから登録されている +message123=このサイトにリンクしているWebページ +message124=上記以外の検索文 +message125=他のユーザ(もしくは匿名ユーザ)のログイン +message126=参照検索エンジン +message127=参照サイト +message128=サマリ +message129=年次の統計では正確な値は表示されません message130=データ配列関数 message131=送信者のEMail message132=受信者のEMail -message133=表示するレポート +message133=レポート対象期間 message134=エキストラ/マーケティング message135=画面解像度 -message136=ワーム/ウィルス攻撃 -message137=お気に入りに追加 -message138=日付 -message139=その他 -message140=Java 対応ブラウザー -message141=Macromedia Director 対応ブラウザー -message142=Flash 対応ブラウザー -message143=Real Audio 対応ブラウザー -message144=Quicktime Audio 対応ブラウザー -message145=Windows Media 対応ブラウザー -message146=PDF 対応ブラウザー +message136=ワーム/ウィルスによる攻撃 +message137=favicon.icoへのヒット(成功のみ) +message138=日別の統計 +message139=その他の情報 +message140=Java 対応ブラウザ +message141=Macromedia Director 対応ブラウザ +message142=Flash 対応ブラウザ +message143=Real Audio 対応ブラウザ +message144=Quicktime Audio 対応ブラウザ +message145=Windows Media 対応ブラウザ +message146=PDF 対応ブラウザ message147=SMTP エラーコード message148=国 message149=メール message150=サイズ message151=最初 message152=最後 -message153=除外フィルター -message154=このチャートのコードは訪問者によるアクセスではありませんので他のチャートに含まれていません。 -message155=クラスター -message156=ロボットによるアクセスは訪問者の閲覧とは違いますので他のチャートに含まれていません。 -message157=+の後の数字は「robots.txt」の表示が成功した回数です。 -message158=ワームによるアクセスは訪問者の閲覧とは違いますので他のチャートに含まれていません。 -message159=閲覧に含まれないアクセスはロボット、ワームなどによるものです。 -message160=閲覧アクセス -message161=閲覧に含まれないアクセス -message162=月 +message153=除外フィルタ +message154=ここにリストされているコードは不可視な訪問者としてカウントされているため、サマリの不可視トラフィック以外のチャートの数値には含まれていません。 +message155=クラスタ +message156=ここにリストされているロボットは不可視な訪問者としてカウントされているため、サマリの不可視トラフィック以外のチャートの数値には含まれていません。 +message157=+の後に表示されている数値は、“robots.txt”ファイルへの参照で検出されたヒット数です。 +message158=ここにリストされているワームは不可視な訪問者としてカウントされているため、サマリの不可視トラフィック以外のチャートの数値には含まれていません。 +message159=不可視トラフィックとは、ワームやロボット、あるいは特殊なHTTPステータスコードを持つ応答などによって生成されたトラフィックのことです。 +message160=可視トラフィック +message161=不可視トラフィック +message162=月別の統計 message163=ワーム -message164=その他のワーム -message165=Mails successfully sent -message166=Mails failed/refused +message164=種類のワーム +message165=送信成功メール +message166=失敗メール message167=Sensitive targets \ No newline at end of file +message168=Javascript disabled +message169=生成 +message170=プラグイン +message171=地域 +message172=都市 +message173=Operaバージョン +message174=Safariバージョン +message175=Chromeバージョン +message176=Konquerorバージョン +message177=, +message178=ダウンロード +message179= +message180= +message181= +message182= +message183= +message184= +message185= +message186= +message187= +message188= +message189= +message190= +message191= +message192= +message193= +message194= +message195= +message196= +message197= +message198= +message199= +message200=yyyy年mmmdd日 +message201=yyyy年breakmmm +message202=yyyy年mmm +message203=mmmbreakdd日 +message204=未分類のrobot (名前に' +message205='を含む) +message206=ウェブドキュメントの収集に使われる標準の*nixツール。恐らくボット。 +message207=Motorolaに偽装したボットとおもわれる +message208=Mozillaに偽装したボットとおもわれる +message209=未分類のrobot (user agent文字列がない) +message210=未分類のrobot ('robots.txt'への参照で検出) +message211=SPAM botによく使われる +message212=特定できないディストリビューション +message213=バージョン不明 +message214=特定できないUnixシステム +message215=未知のサーチエンジン +message216=MS IEに偽装したボットとおもわれる +message217='1', '2' または '3'という名前の一般的なボット +message218=ブラウザがJavaをサポートしていません。ブラウザを替えるか、AWStatsのgraphappletプラグインを無効にしてください。 +message219= +message220= +message221=ここにリストされているヒットは不可視な訪問者としてカウントされているため、サマリの不可視トラフィック以外のチャートの数値には含まれていません。 +message222=yyyy年 +message223=yyyy年 +message224=yyyy年mmm
@@ -17487,18 +17977,27 @@
    else { $FrameName = 'main'; }
 }

+# Here charset is defined, so we can send the http header (Need BuildReportFormat,PageCode)
+if ( !$HeaderHTTPSent && $ENV{'GATEWAY_INTERFACE'} ) {
+   http_head();
+}    # Run from a browser as CGI
+
 # Load Message files, Reference data files and Plugins
 if ($Debug) { debug( "FrameName=$FrameName", 1 ); }
 if ( $FrameName ne 'index' ) {
    &Read_Language_Data($Lang);
    if ( $FrameName ne 'mainleft' ) {
        my %datatoload = ();
+       my $tmpLang = $Lang;
+       if ($tmpLang ne "ja") {
+           $tmpLang = "en";
+       }
        my (
            $filedomains, $filemime, $filerobots, $fileworms,
            $filebrowser, $fileos,   $filese
          )
          = (
-           'domains',  'mime',
+           "domains-$tmpLang",  "mime-$tmpLang",
            'robots',   'worms',
            'browsers', 'operating_systems',
            'search_engines'

GeoIPオプシション

 GeoLite Countryから、GeoIP.datをダウンロードします。Free版より、有償版のほうが精度がいいそうです。GeoIPオプションの指定でGeoIP.datの場所を指定するようになりました。この指定をしないとWindowsのActiveperlは異常終了するようです。GeoIP Perl APIにある通りインストールします。
 unixでは、
perl Makefile.PL
make
make test
make install
 Windows上では、ppmを使います。
C:\>ppm install http://theoryx5.uwinnipeg.ca/ppms/Geo-IP.ppd

Anchorの書式

 IDトークンとNAMEトークンは、アルファベット([A-Za-z])で開始し、任意の数のアルファベット、数字、([0-9])、ハイフン(-)、アンダースコア(_)、コロン、(:)、ピリオド(.)のみで記述する必要がある。(『HTML 4.01仕様書』6 HTMLの基本データ形式)のですが、うちでは、ちゃんと書いてなかったので、
@@ -18051,9 +18550,9 @@
    my $regmisc        = qr/^$miscquoted/;
    my $regfavico      = qr/\/favicon\.ico$/i;
    my $regrobot       = qr/^\/robots\.txt$/i;
-   my $regtruncanchor = qr/#(\w*)$/;
+   my $regtruncanchor = qr/#([A-Za-z0-9\-_:\.]*)$/;
    my $regtruncurl    = qr/([$URLQuerySeparators])(.*)$/;
-   my $regext         = qr/\.(\w{1,6})$/;
+   my $regext         = qr/\.([0-9a-z\-]{1,9})$/;
    my $regdefault;
としています。まじめな方は、
+       my $regtruncanchor=qr/#([A-Za-z][A-Za-z0-9\-_:\.]*)$/;
としましょう。

その他バグ修正

 検索文が複数のパラメタで出てきたときに、全部拾う。
@@ -19961,6 +20479,7 @@
                                             $SearchEnginesKnownUrl{
                                                 $tmprefererserver} )
                                        {  # Search engine with known URL syntax
+                                           my $keyphrasep = "";
                                            foreach my $param (
                                                       split(
                                                           /&/,
@@ -19980,6 +20499,7 @@
                                                    $param =~
 s/^(cache|related):[^\+]+//
                                                      ; # Should be useless since this is for hit on 'not pages'
+                                                   $param = &DecodeEncodedString($param);  # %nnをutf-8にして格納
                                                    &ChangeWordSeparatorsIntoSpace
                                                      ($param)
                                                      ; # Change [ aaa+bbb/ccc+ddd%20eee'fff,ggg ] into [ aaa bbb/ccc ddd eee fff ggg]
@@ -19988,11 +20508,15 @@
                                                    $param =~ tr/ /\+/s;
                                                    if ( ( length $param ) > 0 )
                                                    {
-                                                       $_keyphrases{$param}++;
+                                                       if ( $keyphrasep eq "") {
+                                                           $keyphrasep = "$param";
+                                                       } else {
+                                                       $keyphrasep = $keyphrasep . "+" . "$param";
                                                    }
-                                                   last;
                                                }
                                            }
+                                               if ((length $keyphrasep) > 0) { $_keyphrases{$keyphrasep}++; }
                                        }
                                        elsif (
                                               $LevelForKeywordsDetection >= 2 )
 yahoogleのサポート。検索文がパラメタでなく、後に特定パターンが付きます。
@@ -20049,10 +20574,11 @@
 #                                  debug("xxx".$refurl[0]);
 # If search engine with key inside page url like a9 (www.a9.com/searchkey1%20searchkey2)
                                        if ( $refurl[0] =~
-/$SearchEnginesKnownUrl{$tmprefererserver}(.*)$/
+/$SearchEnginesKnownUrl{$tmprefererserver}(.*)$SearchEnginesKnownUrlTrail{$tmprefererserver}$/
                                          )
                                        {
                                            my $param = $1;
+                                           $param = &DecodeEncodedString($param);  # %nnをutf-8にして格納
                                            &ChangeWordSeparatorsIntoSpace(
                                                                        $param);
                                            $param =~ tr/ /\+/s;
--- /cygdrive/c/awstats-7.7-mod/wwwroot/cgi-bin/lib/search_engines.pm   2018-03-05 11:22:08.706153200 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/cgi-bin/lib/search_engines.pm     2018-03-05 11:20:22.813966900 +0900
@@ -4203,6 +4470,20 @@
 'zoznam','q='
 );

+# SearchEnginesKnownUrlTrail
+# Known rules to extract keywords from a referrer search engine URL
+#------------------------------------------------------------------------------
+%SearchEnginesKnownUrlTrail=(
+# Japanese Search Engines
+# Added by Hobbit_makoto 2007.01.17
+'fresheyedir','\/',
+'idolphoto','\/index[0-9]+\.html',
+'olane','\/c\/\d',
+'yahoogle','\.html',
+);
+
 # SearchEnginesKnownUrlNotFound
 # Known rules to extract not found keywords from a referrer search engine URL
 #------------------------------------------------------------------------------
 GraphAppletプラグインを使用したときに、月(改行)日の表示を可能にしました。
--- /cygdrive/c/awstats-7.7-mod/wwwroot/classes/src/AWGraphApplet.java  2014-09-23 08:16:08.000000000 +0900
+++ /cygdrive/c/AWStats77_jpn/wwwroot/classes/src/AWGraphApplet.java    2014-03-27 16:33:27.041118800 +0900
@@ -186,6 +187,7 @@
            if (i!=-1) {
                //System.out.println("i = " + i);
                sub = s.substring(iOld+1, i);
+               i = i + c.length() - 1;
            } else {
                sub = s.substring(iOld+1, s.length());
                bFin=true;
@@ -352,7 +353,7 @@
            if (blabels[j].indexOf("!")>0) { highlight=1; label=remove(blabels[j],"!"); }

            if (bold==1) { g.setFont(fontb); }
-           String as[] = split(label, "\247", 0);
+           String as[] = split(label, "#br#", 0);
            // Write background for block legend
            if (highlight==1) {
                g.setColor(special_color);

ダウンロード

 ここで動かしたバージョンをawstats77t_jpn.zipとして置いておきます。Windowsで作成しているので、パーミッションとかはありません。unixで使うときは、パーミッションを適切に付けてください。差分は、下記の通りです。
ホーム(x)