#! c:/perl/bin/perl
#
# album3.cgi
# 写真タイトルのリストとそれぞれをコメント付きで表示。
# album2.cgiより追加された機能
# - スライドショーモード
# - ランダム表示モード
# - 写真メニューオフモード
# - 写真枠固定モード
# - リストファイル作成ページ
# - 写真アップロードページ
# - リストファイル無効モード
#
# 3.001 : 9/10/05 : タイトル表示と戻るリンク表示オプションを追加
# 3.0 : 9/6/05 : Created
#
# $Id: album3.cgi,v 1.11 2005/09/10 03:57:07 Hideki Kanayama Exp $
use strict;
use CGI qw(:cgi-lib);
use CGI::Carp qw(fatalsToBrowser);
use GD;
use File::Basename;
use File::Copy;
my $setupfile = "album_setup.pl";
my $adminpwd="albumadmin.txt";
# このスクリプト名
my $script = basename($0);
my $version='3.001';
my $lastupdatedyear='2005';
my $charset = 'Shift_JIS';
#### 環境設定 ここから ##############
# 画像があるディレクトリ(album3.cgiからみた相対パス)
our $imagedir = ".";
# アルバムのリストファイル。写真のファイル名、タイトル、コメントをこの中に書く
# 1:有効 0:無効
our $listfile_en = 1;
our $listfile = "album.lst";
# 戻り先のリンク。 (album3.cgiから見た相対パスとファイル名、絶対パス、httpからの指定でも可)
our $back_en = 1;
our $back = "../..";
our $back_name = '戻る';
# アルバムタイトルの設定
our $title_en = 1;
our $title_color = "#000000";
our $title_size = '+2';
our $title_face = '';
# メニューの位置 0:右 1:左 2:無し
our $menu_locate = 0;
# メニューテキストエリアのサイズ
our $menu_height = 18;
# スライドショー 0:スライドショーボタン無し 1:スライドショーボタンあり 2:強制スライドショー
our $slideshow_en = 0;
our $slideshow_int = 3; #インターバル
# ランダム表示 0:off 1:on
# Only applicable in slide show mode
our $random_mode = 0;
# 写真枠固定モード 0:off 1:on
our $frame_fix_mode = 0;
our $frame_fix_width = 640;
our $frame_fix_height = 480;
# 管理人リンク 0:off 1:on
our $adminlink_en = 1;
# background
our $bgimage_en=0;
our $bgcolor="#ffffff";
our $bgimagefile="";
# 表示幅
our $body_width = 100;
#スタイルシート 1:on 0:off
our $style_sheet_en = 0;
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 = '';
#### 環境設定 ここまで ##############
require "$setupfile" if (-e "$setupfile");
my $q = new CGI;
my $cgierror = $q->cgi_error;
&error($cgierror) if ($cgierror);
my %in = $q->Vars;
%in=&postprocess(%in);
if (! -e "$adminpwd"){
if ($in{mode} eq 'wradminpwd'){
&wradminpwd;
} else {
&setadminpwd;
}
}
if ($in{mode} eq 'setup'){
&setupform;
} elsif ($in{mode} eq 'makesetup'){
&makesetup;
} elsif ($in{mode} eq 'listfileform'){
&listfileform;
} elsif ($in{mode} eq 'makelistfile'){
&makelistfile;
} else {
&dispphoto;
}
exit;
sub dispphoto {
my @filelist;
my @newlist;
my $image;
my $previmage;
my $nextimage;
my $title;
my $line;
my $comment;
my $nexttitle;
my $prevtitle;
my $prevcomment;
my $photoimage;
my $phototitle;
my $photocomment;
my $flag;
my $nextcomment;
my $nextlink1;
my $nextlink2;
my $prevlink;
my $nextlink;
my $caller = 'dispphoto';
if (!open(FILE,"< $listfile") or $listfile_en == 0){
opendir(IMGDIR,"$imagedir") or &error("ディレクトリ$imagedirが開けません");
@filelist = grep !/^\./, readdir IMGDIR;
closedir(IMGDIR);
@newlist = ( grep /\.jpe?g$/i, @filelist);
@newlist = (@newlist, grep /\.gif$/i, @filelist);
@newlist = (@newlist, grep /\.png$/i, @filelist);
@newlist = (@newlist, grep /\.bmp$/i, @filelist);
@newlist = (@newlist, grep /\.tiff?$/i, @filelist);
@newlist = (@newlist, grep /\.ief$/i, @filelist);
@newlist = (@newlist, grep /\.cgm$/i, @filelist);
@newlist = (@newlist, grep /\.pcx$/i, @filelist);
@newlist = (@newlist, grep /\.gd$/i, @filelist);
@newlist = (@newlist, grep /\.gd2$/i, @filelist);
@newlist = (@newlist, grep /\.xbm$/i, @filelist);
@newlist = (@newlist, grep /\.xpm$/i, @filelist);
@filelist = sort @newlist;
&error("画像ファイルが${imagedir}にありません。
画像ファイルを${imagedir}に置くか、管理用から画像ファイルをアップロードするか、
リストファイルを作成し、設定を正しくしてください。") if ($#filelist == -1);
if ($random_mode){
$image = $filelist[rand $#filelist+1];
} else {
if ($in{image} eq ''){
$image = $filelist[0];
$previmage = '';
$nextimage = $filelist[1];
} else {
$image = $in{image};
my $hitnum;
foreach (@filelist){
last if (/^$in{image}$/);
$hitnum++;
}
$previmage = $filelist[$hitnum-1] unless ($hitnum == 0);
$nextimage = $filelist[$hitnum+1] unless ($hitnum >= $#filelist);
}
}
$title = $image;
} else {
flock FILE, 2;
@filelist = ;
close(FILE);
chomp(@filelist);
@filelist = grep !/^\s*$/, @filelist;
@filelist = grep !/^\s*,/, @filelist;
@filelist = grep !/^\s*#/, @filelist;
if ($random_mode){
$line = $filelist[rand $#filelist+1];
($image,$title,$comment)=split(/,/,$line);
} else {
if ($in{image} eq '') {
$line = $filelist[0];
($image,$title,$comment)=split(/,/,$line);
$line = $filelist[1];
($nextimage,$nexttitle,$nextcomment)=split(/,/,$line);
} else {
my $i=0;
foreach (@filelist){
($image,$title,$comment)=split(/,/);
if ($image eq $in{image}){
($nextimage,$nexttitle,$nextcomment)=split(/,/,$filelist[$i+1]);
($previmage,$prevtitle,$prevcomment)=split(/,/,$filelist[$i-1]) unless ($i == 0);
last;
}
$i++;
}
}
}
}
$title = $image if ($title eq '');
$nexttitle = $nextimage if ($nexttitle eq '');
$prevtitle = $previmage if ($prevtitle eq '');
my $imagefile = "$imagedir/$image";
&error("${imagefile}が見つかりません。
管理用からセットアップ、またはリストファイルを修正してください。") unless (-e $imagefile);
&htmlhead($title,'dispphoto',$nextimage);
$flag = 0;
foreach (@filelist){
($photoimage,$phototitle,$photocomment)=split(/,/);
if ($flag == 1) {$nextimage = $photoimage;last;}
if ($image eq $photoimage){$flag = 1;}
}
if ($title_en){
print "$title\n";
}
if ($back_en){
print "
$back_name\n";
}
if ($slideshow_en == 1){
print "
\n";
}
my $cols;
if ($menu_locate == 2){
$cols = 1;
} else {
$cols = 2;
}
print "\n";
print "\n";
if ($menu_locate == 0){
print "| $comment | \n";
print " | \n";
} elsif ($menu_locate == 1) {
print " | \n";
print "$comment | \n";
} elsif ($menu_locate == 2) {
print "$comment | \n";
}
print "
\n";
print "\n";
if ($menu_locate == 1){
&listform($image,\@filelist);
}
my ($set_width, $set_height);
my $td_width;
if ($frame_fix_mode){
my $im;
$image =~ /\.jpe?g$/i and $im = GD::Image->newFromJpeg($imagefile);
$image =~ /\.gif$/i and $im = GD::Image->newFromGif($imagefile);
$image =~ /\.png$/i and $im = GD::Image->newFromPng($imagefile);
$image =~ /\.xbm$/i and $im = GD::Image->newFromxbm($imagefile);
$image =~ /\.gd$/i and $im = GD::Image->newFromgd($imagefile);
$image =~ /\.gd2$/i and $im = GD::Image->newFromgd2($imagefile);
$image =~ /\.xpm$/i and $im = GD::Image->newFromxpm($imagefile);
my ($width, $height) = $im->getBounds();
my $actual_width;
my $actual_height;
if ($width > $frame_fix_width or $height > $frame_fix_height){
my $width_shrink = $frame_fix_width / $width;
my $height_shrink = $frame_fix_height / $height;
my $shrink_ratio;
if ($width_shrink < $height_shrink){
$shrink_ratio = $width_shrink;
} else {
$shrink_ratio = $height_shrink;
}
$actual_width = int($width * $shrink_ratio);
$actual_height = int($height * $shrink_ratio);
} else {
$actual_width = $width;
$actual_height = $height;
}
$set_width = "width=$actual_width";
$set_height = "height=$actual_height";
$td_width = "width=\"$frame_fix_width\"";
} else {
$set_width = '';
$set_height = '';
$td_width = '';
}
if ($nextimage ne ''){
if ($random_mode){
$nextlink1 = "";
} else {
$nextlink1 = "";
}
$nextlink2 = "";
} else {
$nextlink1 = '';
$nextlink2 = '';
}
print "";
print "$nextlink1 $nextlink2";
print " | \n";
if ($menu_locate == 0){
&listform($image,\@filelist);
}
print "
\n";
print "
\n";
if ($previmage eq '') {
$prevlink="$back";
$prevtitle = "トップへ";
} else {
$prevlink = "$script?image=$previmage";
}
if ($nextimage eq '') {
$nextlink="$back";
$nexttitle = "トップへ";
} else {
$nextlink = "$script?image=$nextimage";
}
if ($random_mode == 0){
print qq(\n);
print qq{\n};
print qq{| };
print qq{←$prevtitle};
print qq{ | \n};
print qq{};
print qq{$nexttitle→};
print qq{ | \n};
print qq{
\n};
} else {
print qq{
};
}
if ($adminlink_en) {
print qq{管理用};
}
&htmltail;
}
sub listform {
my $image = shift;
my $filelist = shift;
my %default_image;
my $align;
if ($menu_locate == 0){
$align = 'align=left';
} else {
$align = 'align=right';
}
print "\n";
print "\n";
print "\n";
print " | \n";
}
sub postprocess {
my (%in) = @_;
my $key;
my $value;
while (($key,$value)=each %in){
my $br = "
";
if ($key !~ /^comment/){
$value =~ s/</g;
$value =~ s/>/>/g;
}
if ($value =~ /\r\n/) { $value =~ s/\r\n/$br/g; }
if ($value =~ /\n/) { $value =~ s/\n/$br/g; }
if ($value =~ /\r/) { $value =~ s/\r/$br/g; }
if ($value =~ /,/) { $value =~ s/,/&\#44;/g; }
$in{"$key"}=$value;
}
return(%in);
}
sub makecrypt {
my $plain = shift;
my $salt = join "", ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64];
my $result = crypt($plain,$salt) or crypt($plain,'$1$'.$salt.'$');
return $result;
}
sub checkcrypt {
my ($pwd,$encpwd)=@_;
return(crypt($pwd,$encpwd) eq "$encpwd" or &checkadmin($pwd));
}
sub checkadmin {
my $pwd = shift;
if (open(FILE,"< $adminpwd")){
my $filepwd = ;
close(FILE);
my $inpwd = crypt($pwd,$filepwd);
return ("$inpwd" eq "$filepwd");
} else {
&error('パスワードファイルが存在しません');
}
}
sub setadminpwd {
&htmlhead('管理者用パスワードを入力してください');
print "";
&htmltail;
}
sub wradminpwd {
my $plain = $q->param('pwd');
my $passwd = &makecrypt($plain);
if (open(FILE,"> $adminpwd")){
print FILE "$passwd";
close(FILE);
} else {
&error('パスワードファイル作成に失敗しました');
}
print "Location: $script\n\n";
}
sub setupform {
my $inpwd = $q->param('pwd');
&setadminpwd if ($inpwd eq '');
&error('管理用パスワードが違います。') unless &checkadmin($inpwd);
my @title_check;
my @back_check;
my @menu_locate_check;
my @bgimage_check;
my @listfile_check;
my @slideshow_check;
my @random_check;
my @frame_fix_check;
my @adminlink_check;
my @style_sheet_check;
my @head_insert_check;
$title_check[$title_en] = "checked";
$back_check[$back_en] = "checked";
$menu_locate_check[$menu_locate] = "checked";
$bgimage_check[$bgimage_en] = "checked";
$listfile_check[$listfile_en] = "checked";
$slideshow_check[$slideshow_en] = "checked";
$random_check[$random_mode] = "checked";
$frame_fix_check[$frame_fix_mode] = "checked";
$adminlink_check[$adminlink_en] = "checked";
$style_sheet_check[$style_sheet_en] = "checked";
$head_insert_check[$head_insert_en] = "checked";
&htmlhead('管理人セットアップ');
print "";
&htmltail;
}
###########################################################################
# Setup files write #######################################################
###########################################################################
sub makesetup {
my $inpwd = $q->param('pwd');
&setadminpwd if ($inpwd eq '');
&error('管理用パスワードが違います。') unless &checkadmin($inpwd);
foreach (keys(%in)){
$in{$_} =~ s/
/\n/g;
$in{$_} =~ s/,/,/g;
$in{$_} =~ s/<//g;
}
open(SETUP,"> $setupfile");
print SETUP <〜内に挿入できる構\文 1:on, 0:off
\$head_insert_en = $in{head_insert};
\$head_insert = '$in{head_insert}';
#### 環境設定 ここまで ##############
END
close(SETUP);
print "Location: $script\n\n";
}
sub error {
my ($msg) = shift;
&htmlhead($msg);
print "
$msg\n";
&htmltail;
exit;
}
sub htmlhead {
my $title = shift;
my $caller = shift;
my $nextimage = shift;
my $bgimage;
if ($bgimage_en == 1){
$bgimage = "background=\"$bgimagefile\"";
} else {
$bgimage = "bgcolor=\"$bgcolor\"";
}
print $q->header(-charset=>"$charset");
print "\n";
print "\n";
print "$title\n";
if ($head_insert_en == 1){
print "$head_insert\n";
}
if ($style_sheet_en == 1){
print "\n";
}
my $preload;
if ($caller eq 'dispphoto'){
print <
nextimage = new Image();
function preload(nextpic){
if (nextpic != ''){
nextimage.src = "$imagedir/" + nextpic;
}
}
function showpic(picfile){
self.location="$script?image=" + picfile;
}
JAVASCRIPT
$preload = "onLoad=\"preload(\'$nextimage\')\"" unless ($random_mode);
if ($slideshow_en == 2 or $in{slideshow} eq 'on'){
my $interval;
if ($in{slideshow_int}) {
$slideshow_int = $in{slideshow_int};
$interval = "&slideshow_int=$slideshow_int";
}
my $slideshow = '&slideshow=on';
my $next;
if ($nextimage){
$next = "image=$nextimage";
} else {
$slideshow =~ s/^&//;
}
if ($nextimage or $random_mode){
print "\n";
}
}
}
print "\n";
print "\n";
print "| \n";
}
sub htmltail {
print " $script Ver. $version \n";
print "Copyright(C) $lastupdatedyear, Hideki \n";
print " |
\n";
exit;
}
sub listfileform {
my $inpwd = $q->param('pwd');
&setadminpwd if ($inpwd eq '');
&error('管理用パスワードが違います。') unless &checkadmin($inpwd);
&htmlhead('リストファイル作成');
print "\n";
&htmltail;
}
sub drawlistform {
my ($i, $file, $title, $comment) = @_;
my $file_name = "file_$i";
my $title_name = "title_$i";
my $comment_name = "comment_$i";
print "\n";
print "| ";
print "";
print " | \n";
print "";
print "";
print " | \n";
print "";
print "";
print " | \n";
print "
\n";
}
sub makelistfile {
my $inpwd = $q->param('pwd');
&setadminpwd if ($inpwd eq '');
&error('管理用パスワードが違います。') unless &checkadmin($inpwd);
my $max_line = $q->param('max_line');
open (FILE, "+< $listfile") or open(FILE, "> $listfile") or &error("$listfileが開けません。");
flock FILE, 2;
truncate FILE, 0;
seek FILE, 0, 0;
foreach (0 .. $max_line) {
my $file_name = "file_$_";
my $title_name = "title_$_";
my $comment_name = "comment_$_";
next unless ($in{$file_name});
print FILE "$in{$file_name},$in{$title_name},$in{$comment_name}\n";
}
close(FILE);
unlink($listfile) if (-z $listfile);
foreach (0 .. 9) {
my $upfile = "upfile_$_";
my $upname = "$in{$upfile}";
my $uphandle;
if ($upname) {
&error("画像ディレクトリ${imagedir}が存在しません。") if (! -d "$imagedir");
$uphandle = $q->upload($upfile);
my $cgierror = $q->cgi_error;
&error("$cgierror") if ($cgierror);
my $outfile = "$imagedir/$upname";
copy($uphandle, "$outfile") or &error("アップロードに失敗しました。");
chmod (0666, "$outfile");
}
}
print "Location: $script\n\n";
}