#! /usr/bin/perl # # evcal.cgi # イベントカレンダー # # 1.040 : 7/18/08 : 過去ログ一ヶ月表示のバグを修正 # 1.039 : 6/12/08 : 携帯モードでの管理人オンリーモード変更画面を修正 # 1.038 : 6/10/08 : 携帯モードでの管理人オンリーモードを修正 # 1.037 : 5/27/08 : グループモードを追加 # 1.036 : 5/9/08 : SSIモードの携帯での表示を修正 # 1.035 : 4/28/08 : 携帯モードの今日へジャンプを修正 # 1.034 : 3/21/08 : 過去ログ一ヶ月表示のバグを修正 # 1.033 : 2/24/08 : Macのブラウザでトップへのリンクが機能するよう修正 # 1.032 : 2/15/08 : 管理人オンリーモードでリンク非表示時の携帯モードを修正。プルダウン日付登録を修正 # 1.031 : 1/28/08 : 毎週イベント設定を追加 # 1.030 : 11/10/07 : 携帯モードのパスワードミスのページを修正 # ページ下部へのHTML挿入文を追加 # 過去ログ1ページ表示長の設定を追加 # 管理人オンリーモード時の追加変更リンク非表示オプション追加 # 1.029 : 10/16/07 : 携帯モード「今日へジャンプ」リンクを追加 # 1.028 : 9/13/07 : 携帯モードで記念日を正確に表示できるよう修正 # 1.027 : 9/1/07 : SSIモードで記念日を正確に表示できるよう修正 # 1.026 : 7/29/07 : 記念日に第何曜日指定を出来るように修正 # 1.025 : 5/22/07 : 携帯用のトップへのリンクオプションを追加 # 1.024 : 3/24/07 : タグのミスを修正 # 1.023 : 1/14/07 : SSIモードの複数行表示を修正 # 1.022 : 12/5/06 : カラーコードの#を自動で付加するよう修正 # 1.021 : 11/6/06 : SSIモードのイベント無しメッセージが無いときの処理を修正 # 1.020 : 11/5/06 : SSIモードを強化 # 1.019 : 8/14/06 : データファイルのパーミッションを修正 # 1.018 : 8/6/06 : フォームのテキストを修正 # 1.017 : 6/27/06 : 半角スペースを表示するように修正 # 1.016 : 6/26/06 : 過去ページの戻るリンク名を修正 # 1.015 : 6/20/06 : 管理人オンリーモードを追加 # 1.014 : 6/14/06 : 更新リンクを更新者にした時のリンクを修正 # 1.013 : 6/13/06 : 携帯モードを追加 # 1.012 : 10/31/05 : 記念日オプションを追加 # 1.011 : 10/29/05 : 表示開始月のオプションを追加 # 1.010 : 10/11/05 : カラーコードのチェックを追加 # 1.009 : 10/6/05 : 書きこみイベント日の背景色変更のオプションを追加 # 1.008 : 10/1/05 : Copyrightにリンクを追加 # 1.007 : 9/25/06 : テンポラリファイルが残るバグを修正 # 1.006 : 9/19/05 : 更新リンクを更新者にするオプションを追加 # その際のURLの自動リンク機能を追加 # 1.005 : 8/29/05 : デコードを修正 # 1.004 : 8/25/05 : cryptを修正 # 1.003 : 8/22/05 : 更新者欄の幅を変更できるオプションを追加 # 1.002 : 8/12/05 : データファイルが無い時のエラー処理を追加 # 1.001 : 8/9/05 : SSIモード追加 # 1.0 : 8/8/05 : 一般公開のために大幅改良 # # http://www.hidekik.com/ # # $Id: evcal.cgi,v 1.78 2008/07/18 14:57:49 Hideki Kanayama Exp $ # Copyright(c) 1997-2008, Hideki Kanayama, All rights reserved.# use File::Basename; use Time::Local; use strict; use CGI::Carp qw(fatalsToBrowser); use CGI qw(:cgi-lib); my $lastupdatedyear = 2008; my $version = "1.040"; my $script = basename($0); my $setupfile = "evcal_setup.pl"; my $admindat = "adminpwd.dat"; my $groupdat = "grouppwd.dat"; my $lang = 0; ##################################### # データファイル名 our $datafile = "eventcal.dat"; # lockfile our $lockfile = "lockfile.dat"; # 戻りリンク 1:on 0:off our $backlink_en = 1; our $backlink = "../evcal.html"; our $backlink_name = '【戻る】'; our $mob_backlink = "../evcal.html"; our $mob_backlink_name = '【戻る】'; # バックグラウンド our $bgimage_en = 0; our $bgcolor = 'white'; our $bgimage_file = ''; # カレンダーの色 # ヘッダの背景 our $table_head_bgcolor = 'white'; # ヘッダの文字 our $table_head_color = 'black'; # 更新者の色 our $post_name_color = 'black'; # 更新日の色 our $post_update_color = 'black'; # 平日の背景 our $weekday_bgcolor = 'white'; # 土曜日の背景 our $sat_bgcolor = '#ccffff'; # 日曜日の背景 our $sun_bgcolor = '#ffcccc'; # 日付、内容の文字色はスタイルシートのリンク色の設定で行ってください。 # 日付はclass=daylink, コメントはclass=comlinkとなっています。 # 更新リンク 0:内容 1:更新者 our $update_link = 0; # 更新者を内容更新のリンクに設定した場合はスタイルシートで色の設定を # 行ってください。class=namelinkとなっています。 # その場合の内容の色 our $post_com_color = 'black'; # 本文中のリンクを文字列に置き換える 1:on 0:off # この機能をONにするには更新リンクを更新者に設定してください。 our $link_replace_en = 1; our $link_replace = 'リンクはこちら'; our $link_replace_top_en = 0; # 書き込んだイベントのバックグランドの色 1:on 0:off our $day_bgcolor_en = 0; # 表の幅 our $body_width = 100; # 更新者欄の幅 our $name_width = 10; #表示開始月 0:今月 1:先月 our $start_month = 0; # 表示する月数 our $disp_length = 12; our $disp_length_other = ''; # 過去ログ表示月数 0:一ヶ月 1:1年 our $past_length = 1; # タイトル our %title = ( display => { text => 'イベントカレンダー', image => '', color => 'black', size => '+1', face => '', style => '', sel => 0, # 0:デフォルト、1:テキスト、2:ロゴ、3:スタイルシート loc => 1, # 0:左、1:中、2:右 }, register => { text => 'のイベント登録', image => '', color => 'black', size => '+1', face => '', style => '', sel => 0, # 0:デフォルト、1:テキスト、2:ロゴ、3:スタイルシート loc => 1, # 0:左、1:中、2:右 }, modify => { text => 'のイベントの変更', image => '', color => 'black', size => '+1', face => '', style => '', sel => 0, # 0:デフォルト、1:テキスト、2:ロゴ、3:スタイルシート loc => 1, # 0:左、1:中、2:右 }, setadminpwd => { text => '管理人用パスワードを設定してください。', sel => 4, }, setgradminpwd => { text => 'グループ用パスワードを設定してください。', sel => 4, }, setup => { text => '管理人セットアップ', sel => 4, }, ); # ジャンプリンク 1:on 0:off our $jumplink_en = 1; our $jumplink_name = '【「今日」へジャンプ】'; # 携帯モードリンク 1:on 0:off our $mobilelink_en = 1; our $mobilelink_name = '【携帯モード】'; # セットアップリンク 1:on 0:off our $setup_en = 1; our $setup_name = '【管理用】'; # 記念日設定 our $anniv_en = 0; our $anniv = '1,1,#ffcccc,#0000ee,元旦 1,dai-2-mon,#ffcccc,#0000ee,成人の日 2,11,#ffcccc,#0000ee,建国記念日 4,29,#ffcccc,#0000ee,昭和の日 5,3,#ffcccc,#0000ee,憲法記念日 5,4,#ffcccc,#0000ee,みどりの日 5,5,#ffcccc,#0000ee,子供の日 7,dai-3-mon,#ffcccc,#0000ee,海の日 9,dai-3-mon,#ffcccc,#0000ee,敬老の日 10,dai-2-mon,#ffcccc,#0000ee,体育の日 11,3,#ffcccc,#0000ee,文化の日 11,23,#ffcccc,#0000ee,勤労感謝の日 12,23,#ffcccc,#0000ee,天皇誕生日'; # グループモード our $group_en = 0; # 管理人オンリーモード our $adminonly_en = 0; # 管理人オンリーモード時に登録ボタンとリンクの表示 1:表示, 0:非表示 our $admin_reglinks = 1; # SSIモード # イベントが無い時の表示 our $ssi_noev_msg = 'イベントはありません。'; # 本日を含めてイベントを表示する日数 our $ssi_evdisp = 3; # イベント表示時の日付表示 1:on 0:off our $ssi_evdate_en = 1; #スタイルシート 1:on 0:off our $style_sheet_en = 1; our $style_sheet = ' A:link {text-decoration: none} A:visited {text-decoration: none} A:active {text-decoration: none} '; #
〜内に挿入できる構文 1:on, 0:off our $head_insert_en = 0; our $head_insert = ''; #使い方 our $usage_en = 1; our $usage_name = '【使い方】'; our $usage = '\n";
} else {
&inputform($now) unless ($adminonly_en and $admin_reglinks == 0);
print "$body_insert3\n" if ($body_insert3_en == 1);
&updateinfo;
print "$body_insert4\n" if ($body_insert4_en == 1);
&misclink($now);
print "$body_insert5\n" if ($body_insert5_en == 1);
}
($caldata, $calname, $caldate, $calid, $pastyear, $calbg, $calfg) = &getevdata;
my @pastarray;
# if ($in{mode} ne 'past'){
@pastarray = sort {$a <=> $b} @{$pastyear};
if ($#pastarray != -1){
foreach ($pastarray[0] .. $year+1900){
print "$_年 ";
}
}
# }
if ($in{mode} eq 'past'){
print "
\n";
foreach (1 .. 12){
if ($past_length){
print "$_月 \n";
} else {
print "$_月 \n";
}
}
}
print "$body_insert6\n" if ($body_insert6_en == 1 && $in{mode} ne 'past');
print "
| 日付 | \n"; print "内容 | \n"; print "更新者 | \n"; print "更新日 | \n"; print "||
|---|---|---|---|---|---|
| "; if ($in{mode} eq 'past'){ print "$mon月$day日 | \n"; } else { if ($adminonly_en and $admin_reglinks == 0){ print "$weekday[$wday]"; print " | \n"; my $day_bgcolor; my $j; for ($j=0;$j<=$#comment;$j++){ chomp($comment[$j]); next if ($comment[$j] eq ''); if ($id[$j] eq 'anniv') { if ($day_bgcolor[$j] ne 'default') { $day_bgcolor = "$day_bgcolor[$j]"; } else { $day_bgcolor = "$col_bgcolor"; } } else { if ($day_bgcolor[$j] ne '' and $day_bgcolor_en){ $day_bgcolor = "$day_bgcolor[$j]"; } else { $day_bgcolor = "$col_bgcolor"; } } if ($day_fgcolor[$j] eq 'default'){ $day_fgcolor[$j]='black'; } print ""; if ($comment[$j] ne ' ' && $in{mode} ne 'past') { $comment[$j] =~ s/ / /g; if ($update_link == 0){ if ($id[$j] eq 'anniv'){ print "$comment[$j]"; } else { if ($adminonly_en and $admin_reglinks == 0){ $comment[$j] = &link_replace($comment[$j]); print "$comment[$j]"; } else { print "$comment[$j]"; } } } else { if ($id[$j] eq 'anniv'){ print "$comment[$j]"; } else { $comment[$j] = &link_replace($comment[$j]); print "$comment[$j]"; } } } else { if ($id[$j] eq 'anniv'){ print "$comment[$j]"; } else { $comment[$j] = &link_replace($comment[$j]); print "$comment[$j]"; } } print " | \n"; print ""; if ($update_link == 0){ if ($id[$j] eq 'anniv' or $name[$j] eq ' '){ print " \n"; } else { print "$name[$j]\n"; } } else { if ($id[$j] eq 'anniv' or $name[$j] eq ' '){ print " \n"; } else { if ($adminonly_en and $admin_reglinks == 0){ print "$name[$j]\n"; } else { print "$name[$j]"; } } } print " | \n"; my $updatedate; $updatedate = &calupdate($update[$j]); if ($id[$j] eq 'anniv'){ print "\n"; } else { print " | $updatedate | \n"; } print "
【イベントカレンダーへ】
\n" if ($in{mode} eq 'past');
&usage unless ($in{mode} eq 'past');
print "
$body_insert7\n" if ($body_insert7_en == 1);
&htmltail;
}
sub evmobile {
&htmlhead($title{display}{text});
print "$mob_backlink_name
\n"; print "$title{display}{text}
"; print "今日へジャンプ
\n"; &inputform($now) unless ($adminonly_en and $admin_reglinks == 0); &updateinfo; if ($adminonly_en and $admin_reglinks == 0){ print "管理用
\n"; } my ($caldata, $calname, $caldate, $calid, $pastyear, $calbg, $calfg) = &getevdata; print "
| \n";
}
}
sub htmltail {
my $mysite = ('http://www.hidekik.com/','http://www.hidekik.com/en/')[$lang];
if ($in{mobile} eq 'on' or $in{mode} =~ /mobile/){
print " evcal.cgi Ver. $version\n"; print "Copyright(C) 1997-$lastupdatedyear, hidekik.com\n"; print "\n"; } else { print " evcal.cgi Ver. $version \n";
print "Copyright(C) 1997-$lastupdatedyear, hidekik.com \n";
print " |
管理人用イベント登録・変更
\n";
&inputform($now);
&editbutton;
}
} else {
print "
";
$colwidth = 30;
} else {
&htmlhead($title{$subname}{text});
print "$titleprint";
$colwidth = 50;
}
print <
HTMLOUT
if ($day_bgcolor_en and $in{mobile} ne 'on'){
print "イベント日の色(オプション) \n";
}
if ($in{mobile} eq 'on'){
print "\n";
}
if ($group_en){
print < ";
$colwidth = 30;
} else {
&htmlhead($title{$subname}{text});
print "$titleprint";
$colwidth = 50;
}
my $j;
my $dataline;
my $name;
my $id;
my $bg;
for ($j=0;$j<=$#comment;$j++){
next unless ($in{id} == $id[$j]);
$dataline = $comment[$j];
$dataline =~ s/
HTMLOUT
if ($day_bgcolor_en and $in{mobile} ne 'on'){
print "イベント日の色(オプション) \n";
}
if ($in{mobile} eq 'on'){
print "\n";
}
print < \n";
}
sub inputform {
my $now = shift;
my $n;
my $nn;
my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=gmtime($now);
print " \n";
}
sub usage {
if ($usage_en == 1){
print <
内容
\n";
print "
HTMLOUT2
}
print <
HTMLOUT3
&htmltail;
}
sub modify {
my $subname = 'modify';
if ($adminonly_en and $admin_reglinks == 0){
foreach my $key1 (split /&/, $in{param}){
my ($key,$elem) = split /=/, $key1;
$in{$key} = $elem;
}
}
$title{$subname}{text} = "$in{year}年$in{month}月$in{day}日($weekday[$in{weekday}])$title{$subname}{text}";
my $caldata;
my $calname;
my $caldate;
my $calid;
my $pastyear;
my $calbg;
($caldata, $calname, $caldate, $calid, $pastyear, $calbg) = &getevdata;
my @comment = ();
my @name = ();
my @update = ();
my @id = ();
my @bg = ();
if (exists $calname->{$in{year}}{$in{month}}{$in{day}}) {
@comment = split /
/\n/g;
$dataline =~ s/\n*$//;
$name = $name[$j];
$id = $id[$j];
$bg = $bg[$j];
last;
}
print <
内容
\n";
print "
HTMLOUT2
&htmltail;
}
sub evwrite {
&error('名前とパスワードは必ず入力してください。') if ($in{name} eq '' || $in{pwd} eq '');
if ($adminonly_en and !&checkadmin($in{pwd})) {
&error('管理人オンリーモードでの管理人パスワードが違います。');
}
if ($group_en && !&checkcrypt($in{grouppwd},$grouppwd)) {
my $message = 'グループ用パスワードが違います。';
&error($message);
}
if ($day_bgcolor_en){
&error("無効なカラーコード、$in{day_bgcolor}です。") unless &color_check($in{day_bgcolor});
}
&lockfile;
my ($id) = &getevdata(-lastid);
$id++;
my $pwd = &makecrypt($in{pwd});
my $now = time+$offset*3600;
my $day_bgcolor = $day_bgcolor_en ? $in{day_bgcolor} : '';
$day_bgcolor =~ s/^([\da-f]{6})$/\#$&/i;
open WR, ">> $datafile" or &error("データファイル$datafileが開けません。");
print WR "$id,$in{year},$in{month},$in{day},$in{name},$now,$pwd,$host,$ip,$in{comment},$day_bgcolor\n";
close WR;
&unlockfile;
chmod (0666, "$datafile");
if ($in{mobile} eq 'on'){
print "Location: $script?mode=mobile\n\n";
} else {
print "Location: $script#${in{year}}_${in{month}}_${in{day}}\n\n";
}
}
sub evreplace {
&error('名前とパスワードは必ず入力してください。') if ($in{name} eq '' || $in{pwd} eq '');
if ($day_bgcolor_en){
&error("無効なカラーコード、$in{day_bgcolor}です。") unless &color_check($in{day_bgcolor});
}
&lockfile;
my $now = time+$offset*3600;
my ($dyear,$dmonth,$dday,$dname,$dnow,$dpwd,$dhost,$dip,$dcomment,$day_bgcolor);
my $id;
open DATA, "< $datafile" or &error("データファイル$datafileが開けません。");
open WR, "> tmp.$$" or &error("テンポラリファイルが開けません。");
while (){
chomp;
($id,$dyear,$dmonth,$dday,$dname,$dnow,$dpwd,$dhost,$dip,$dcomment,$day_bgcolor) = split /,/;
chomp;
if ($id == $in{id}){
if (!checkcrypt($in{pwd}, $dpwd)){
close(WR);
&error('修正用パスワードが違います。');
}
$in{day_bgcolor} =~ s/^([\da-f]{6})$/\#$&/i;
print WR "$in{id},$in{year},$in{month},$in{day},$in{name},$now,$dpwd,$host,$ip,$in{comment},$in{day_bgcolor}\n";
} else {
print WR "$id,$dyear,$dmonth,$dday,$dname,$dnow,$dpwd,$dhost,$dip,$dcomment,$day_bgcolor\n";
}
}
close WR;
close DATA;
rename("tmp.$$","$datafile");
&unlockfile;
chmod (0666, "$datafile");
if ($in{mobile} eq 'on'){
print "Location: $script?mode=mobile\n\n";
} else {
print "Location: $script#${in{year}}_${in{month}}_${in{day}}\n\n";
}
}
sub calupdate {
my $now = shift;
return $now if ($now eq ' ');
my ($sec,$min,$hour,$day,$mon,$year,$wday,$yday,$isdst)=gmtime($now);
$mon++;
$year += 1900;
my $update = "$mon/$day/$year";
return $update;
}
sub getevdata {
# options
# -lastid : Return the last id in the data file
# -latest : Return the latest update information in the data file
# -alldta : Retrun hash reference for all registered contents in the data file
# (default)
my @options = @_;
my %caldata;
my %calname;
my %caldate;
my %calid;
my %calbg;
my %calfg;
my $id;
my ($dyear,$dmonth,$dday,$dname,$dnow,$dpwd,$dcomment,$day_bgcolor,$day_fgcolor);
my $host;
my $ip;
my $data_day;
my $latest;
my ($lid,$lyear,$lmonth,$lday,$lname,$lnow);
my @pastyear;
if ((grep /-alldata/, @options or $#options == -1) and $anniv_en and $anniv ne '') {
my @anniv_data = split /[\r\n]/, $anniv;
foreach (@anniv_data){
chomp;
($dmonth,$dday,$day_bgcolor,$day_fgcolor,$dcomment) = split /,/;
$dday = lc($dday);
$dmonth = lc($dmonth);
$day_bgcolor ||= 'default';
$day_fgcolor ||= 'default';
$dyear = 'anniv';
if (grep /-alldata/, @options or $#options == -1) {
if (exists $caldata{$dyear}{$dmonth}{$dday}) {
next if ($dcomment eq '');
$caldata{$dyear}{$dmonth}{$dday} .= "
\n" if ($in{mode} eq 'mobile');
print "最終更新日は ";
print "$datetimeです。
\n";
my ($nsec,$nmin,$nhour,$nday,$nmon,$nyear,$nwday,$nyday,$nisdst)=gmtime($now);
my $start_table_date = timegm(0,0,0,1,$nmon,$nyear);
my $dmonth_n = $dmonth - 1 if ($dmonth != 0);
$dday = 1 if ($dday eq '');
my $last_written_date = timegm(0,0,0,$dday,$dmonth_n,$dyear);
print "イベントが更新された日は、";
if ($in{mode} eq 'mobile'){
print "$newest";
} else {
if ($last_written_date < $start_table_date){
if ($past_length) {
print "$newest";
} else {
print "$newest";
}
} else {
print "$newest";
}
}
print "です。
\n"; } sub monthdaycheck { my ($year,$month,$day) = @_; my @monthdays = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); my $md = $monthdays[$month]; ++$md unless $month != 1 or $year % 4 or !($year % 400); $month++; &error("日付が適切ではありません。$month月$day日") if $day > $md or $day < 1; } sub setup { my $subname = 'setup'; &setadminpwd if ($in{pwd} eq ''); &error('管理用パスワードが違います。') unless &checkadmin($in{pwd}); &htmlhead($title{$subname}{text}); my %check; $check{backlink}[$backlink_en] = "checked"; $check{bgimage}[$bgimage_en] = "checked"; $check{title}{display}{sel}[$title{display}{sel}] = "checked"; $check{title}{display}{loc}[$title{display}{loc}] = "checked"; $check{title}{register}{sel}[$title{register}{sel}] = "checked"; $check{title}{register}{loc}[$title{register}{loc}] = "checked"; $check{title}{modify}{sel}[$title{modify}{sel}] = "checked"; $check{title}{modify}{loc}[$title{modify}{loc}] = "checked"; $check{style_sheet}[$style_sheet_en] = "checked"; $check{head_insert}[$head_insert_en] = "checked"; $check{usage}[$usage_en] = "checked"; $check{jumplink}[$jumplink_en] = "checked"; $check{mobilelink}[$mobilelink_en] = "checked"; $check{setup}[$setup_en] = "checked"; $check{start_month}[$start_month] = "checked"; $check{disp_length}[$disp_length] = "checked"; $check{disp_length}[13] = "checked" if (!grep /checked/, @{$check{disp_length}}[1,3,6,12]); $check{past_length}[$past_length] = "checked"; $check{body_insert1}[$body_insert1_en] = "checked"; $check{body_insert2}[$body_insert2_en] = "checked"; $check{body_insert3}[$body_insert3_en] = "checked"; $check{body_insert4}[$body_insert4_en] = "checked"; $check{body_insert5}[$body_insert5_en] = "checked"; $check{body_insert6}[$body_insert6_en] = "checked"; $check{body_insert7}[$body_insert7_en] = "checked"; $check{update_link}[$update_link] = "checked"; $check{link_replace_en}[$link_replace_en] = "checked"; $check{link_replace_top_en}[$link_replace_top_en] = "checked"; $check{day_bgcolor_en}[$day_bgcolor_en] = "checked"; $check{anniv_en}[$anniv_en] = "checked"; $check{group_en}[$group_en] = "checked"; $check{adminonly_en}[$adminonly_en] = "checked"; $check{admin_reglinks}[$admin_reglinks] = "checked"; $check{ssi_evdate_en}[$ssi_evdate_en] = "checked"; print "
"; &htmltail; } sub setupwrite { $in{title_display_size} =~ s/ /+/; $in{title_register_size} =~ s/ /+/; $in{title_modify_size} =~ s/ /+/; foreach (keys(%in)){ $in{$_} =~ s/管理人用イベント登録・変更
\n";
&inputform($now);
&editbutton;
}
&htmltail;
}