#!/usr/bin/perl
#-----------------------------------------------------------
# 私本管理GOOUT for SmartPhone By:EKAKIN
#-----------------------------------------------------------
#
#-----------------------------------------------------------
# 動作環境
#-----------------------------------------------------------
# Perl 5.8.1 以降。
# Perl 5.8.0 は文字コードの扱いに問題があるため、
# 文字化けを起こす等の不具合が発生する可能性があります
# なお、jcode.plは使用しなくなりました
#-----------------------------------------------------------
#
#-----------------------------------------------------------
# 改版履歴
#-----------------------------------------------------------
#2015.01.10 Ver2.1.0 modified by shela
# 私本管理 Ver.4のバックアップデータ(*.shn,*.csv)に対応
# ISBNのチェックディジット計算のバグ修正
# バックアップデータのヘッダ行を無視するように修正
# 一括画像ローカル保存プラグインに対応
#2015.01.10 Ver2.0.1 検索時、特定の文字列が文字化けして正しく検索できない不具合を修正
# 画像が正しく表示されない不具合を修正
#2011.08.07 Ver2.0.0 改名
# UI変更
#2010.08.11 Ver1.0.0 公開
# 【Thank you for kmzw】
#-----------------------------------------------------------
use strict;
use utf8;
use CGI qw/:standard :netscape/;
use Encode qw/decode_utf8/;
use HTML::Entities qw/encode_entities/;
my $TITLE = "私本管理GOOUT"; # タイトル
my $VERSION = "Ver 2.1.0"; # バージョン
my $SCRIPT_NAME = "$ENV{'SCRIPT_NAME'}"; # CGIファイル名
#-----------------------------------------------------------
# カスタマイズ
#-----------------------------------------------------------
my $PAGE = 20; # 1ページに表示する件数
# 「No Image」画像の場所を指定します
# cgiと同じ場所の場合は「noimage.jpg」と指定します
# @niftyの場合は「http://homepage○.nifty.com/○○○/ディレクトリ/noimage.jpg」で指定します
# ↓このままでも使用できますが、変更される可能性があります
my $NOIMAGE = "http://homepage1.nifty.com/EKAKIN/cgi/goout/noimage.jpg";
# For iPhone
my $ICON_PATH = "http://homepage1.nifty.com/EKAKIN/cgi/goout/iphone_icon.png";
my $LINK_URL = "http://www.amazon.co.jp/gp/aw/d/";
my $AMAZON_TAG = "";
#-----------------------------------------------------------
# 検索ファイル名(フォルダと対になるように追加してください)
#-----------------------------------------------------------
my @FILE = ( "123.csv" );
#-----------------------------------------------------------
# 検索フォルダ名(ファイルと対になるように追加してください)
#-----------------------------------------------------------
my @DIR = ( "デフォルト" );
#===========================================================
# 実行処理
#===========================================================
my %FORM = ();
my %FDATA = ();
my @FDATAindex = ();
# フラグ付きUTF-8文字列をフラグなしにして出力させる
binmode STDOUT, ":utf8";
# フォームの内容取得
&formDataGet;
if ( $ENV{'REQUEST_METHOD'} eq "POST"
|| defined( $FORM{page} ) && $FORM{page} ne "" )
{
# 検索結果画面表示
&htmlResult;
}
else {
# 検索画面表示
&htmlStart;
}
exit;
#-----------------------------------------------------------
# 検索画面表示
#-----------------------------------------------------------
sub htmlStart {
&htmlHeader01;
&htmlSearch; # 検索画面
&htmlFooter01;
}
#-----------------------------------------------------------
# 検索結果表示
#-----------------------------------------------------------
sub htmlResult {
&htmlHeader02;
&runSearch; # 検索処理
&htmlFooter02;
}
#-----------------------------------------------------------
# スタイルシート
#-----------------------------------------------------------
sub Style {
print <<"_EOF_";
_EOF_
}
#-----------------------------------------------------------
# HTML ヘッダ初期
#-----------------------------------------------------------
sub htmlHeader01 {
print "Content-type: text/html\n\n";
print <<"_EOF_";
$TITLE
_EOF_
&Style;
print <<"_EOF_";
_EOF_
}
#-----------------------------------------------------------
# HTML ヘッダ検索後
#-----------------------------------------------------------
sub htmlHeader02 {
print "Content-Type: text/html\n\n";
print <<"_EOF_";
$TITLE
_EOF_
&Style;
print <<"_EOF_";
_EOF_
}
#-----------------------------------------------------------
# HTML フッタ初期
#-----------------------------------------------------------
sub htmlFooter01 {
print << "_EOF_";
_EOF_
}
#-----------------------------------------------------------
# HTML フッタ検索後
#-----------------------------------------------------------
sub htmlFooter02 {
print << "_EOF_";
_EOF_
}
#-----------------------------------------------------------
# HTML 検索画面
#-----------------------------------------------------------
sub htmlSearch {
print <<"_EOF_";
_EOF_
}
#-----------------------------------------------------------
# 検索内容取得
#-----------------------------------------------------------
sub formDataGet {
# 入力パラメータ取得
foreach my $key (param) {
$key = decode_utf8($key);
my $value = decode_utf8( param($key) );
if ( $key =~ /data(\d+)/ ) {
my $index = $1;
if ( $index eq "0" ) {
# ISBN
$FDATA{$index} = &isbn_change($value);
}
else {
# ISBN以外は小文字にして保持
$FDATA{$index} = lc($value);
}
unless ( $FDATA{$index} eq "" ) {
push( @FDATAindex, $index );
}
}
else {
# ジャンル、検索タイプ(AND/OR)、ページ
$FORM{$key} = $value;
}
}
}
#-----------------------------------------------------------
# 検索処理
#-----------------------------------------------------------
sub runSearch {
# ファイルの読み込み
if ( !open( FH, "<:raw", $FILE[ $FORM{file} ] ) ) {
&error( "エラー",
"私本管理バックアップファイルが読み込めません"
);
return;
}
# 初期ページを設定
if ( !defined( $FORM{page} ) || $FORM{page} eq "" ) {
$FORM{page} = 1;
}
my $maxRec = $FORM{page} * $PAGE; # 表示レコード MAX
my $minRec = $maxRec - $PAGE + 1; # 表示レコード MIN
print "\n";
my ( $codeSet, $offset );
my $count = 0;
my $flg = 0;
while ( my $line = ) {
if ( $. == 1 ) {
if ( $line =~ s/^\xEF\xBB\xBF// ) {
$codeSet = "utf8";
$offset = 3;
}
elsif ( $line =~ s/^\xFF\xFE// ) {
$codeSet = "utf16le";
$offset = 2;
}
else {
$codeSet = "cp932";
$offset = 0;
}
# BOMを除いた先頭へ戻って読み直し
seek( FH, $offset, 0 );
binmode FH, "encoding($codeSet):crlf:utf8";
$line = ;
}
chomp($line); # 改行を取り除く
# 「,」区切りでCSVファイル1行読込
my @array = split( ",", $line );
# ヘッダ行を読み飛ばす
if ( $array[0] eq "ISBN" ) {
next;
}
my $found = 0;
# 検索
if ( $#FDATAindex == -1 ) {
# 検索項目が未入力の場合は該当ありと判定
$found = 1;
}
elsif ( $FORM{ftype} eq "or" ) {
# OR検索の場合は最初に一致項目が出た時点で該当ありと判定
$found = 0;
my $data;
for ( my $i = 0; $i <= $#FDATAindex; $i++ ) {
$data = $array[ $FDATAindex[$i] ];
$data = lc($data);
# ISBNは-を削除 x,+,*はXとみなす
if ( $FDATAindex[$i] == 0 ) {
$data = &isbn_change($data);
}
if ( index( $data, $FDATA{ $FDATAindex[$i] } ) > -1 ) {
$found = 1;
last;
}
elsif ( $FDATAindex[$i] == 1 || $FDATAindex[$i] == 5 ) {
# タイトルカナ検索 / 作者カナ検索
my $n = int( $FDATAindex[$i] ) + 1;
$data = $array[$n];
$data = lc($data);
if ( index( $data, $FDATA{ $FDATAindex[$i] } ) > -1 ) {
$found = 1;
last;
}
}
}
}
elsif ( $FORM{ftype} eq "and" ) {
# AND検索の場合は最初に不一致項目が出た時点で該当なしと判定
$found = 1;
my $data;
for ( my $i = 0; $i <= $#FDATAindex; $i++ ) {
$data = $array[ $FDATAindex[$i] ];
$data = lc($data);
# ISBNは-を削除 x、+、*はXとみなす
if ( $FDATAindex[$i] == 0 ) {
$data = &isbn_change($data);
}
if ( index( $data, $FDATA{ $FDATAindex[$i] } ) == -1 ) {
# タイトルカナ検索 / 作者カナ検索
if ( $FDATAindex[$i] == 1 || $FDATAindex[$i] == 5 ) {
my $n = int( $FDATAindex[$i] ) + 1;
$data = $array[$n];
$data = lc($data);
if ( index( $data, $FDATA{ $FDATAindex[$i] } ) == -1 )
{
$found = 0;
last;
}
}
else {
$found = 0;
last;
}
}
}
}
# 検索にヒットした場合
if ($found) {
$count++;
if ( $minRec <= $count && $maxRec >= $count ) {
# ISBN
$array[0] =~ s/-//g; # ハイフンを除去
$array[0] =~ s/^978|^979//g; # 先頭に978か979があれば(ISBN13)除去
$array[0] =~ s/.$//g; # チェックデジット除去
# チェックデジット計算
my @num_splt = split( //, $array[0] ); # 1文字ずつ分割
my $check = 0;
for ( my $i = 0; $i < 9; $i++ ) {
$check = $check + $num_splt[$i] * ( 10 - $i );
}
$check = 11 - ( $check % 11 );
if ( $check == 10 ) {
$check = "X";
}
elsif ( $check == 11 ) {
$check = 0;
}
# タイトル
$array[1] =~ s/"//g;
$array[1] = encode_entities( $array[1] );
# 巻
$array[4] =~ s/"//g;
if ( $array[4] eq "ONLY ONE" ) {
$array[4] = "";
}
$array[4] = encode_entities( $array[4] );
# 作者
$array[5] =~ s/"//g;
$array[5] = encode_entities( $array[5] );
# 発行所
$array[12] =~ s/"//g;
$array[12] = encode_entities( $array[12] );
# 一括画像ローカル保存プラグイン利用時は備考6を画像のURLとする
if ( length( $array[37] ) > 0
&& substr( $array[37], 1, 1 ) eq ":" )
{
$array[37] = $array[66];
}
# 画像がない場合
if ( $array[37] eq "" ) {
$array[37] = $NOIMAGE;
}
print "- ";
print
"";
print
"";
print "
$array[1] $array[4]
";
print "$array[5]
";
print "$array[12]
";
print "ISBN:$array[0]$check
";
print "";
print " \n";
}
else {
$flg = 1;
}
$found = 0;
}
}
close(FH);
if ( $count == 0 ) {
print "該当データなし
\n";
}
else {
print
"\n該当データ:${count}件
\n";
}
print "\n";
if ( $flg == 1 ) {
my $p = $FORM{page};
my $maxPage = int( $count / $PAGE );
if ( $count % $PAGE != 0 ) {
$maxPage++;
}
# 指定ページが範囲外の場合は先頭または最終ページにする
if ( $p < 1 ) {
$p = 1;
}
elsif ( $p > $maxPage ) {
$p = $maxPage;
}
print "- ";
if ( $p > 1 ) {
$FORM{page} = $p - 1;
print "<";
}
print "
- $p\/$maxPage
";
print "- ";
if ( $p < $maxPage ) {
$FORM{page} = $p + 1;
print ">";
}
print "
\n";
print "\n";
for ( my $pagecount = 1; $pagecount <= $maxPage; $pagecount++ ) {
if ( $pagecount != $p ) {
print
"- $pagecount
\n";
}
else {
print "- $pagecount
\n";
}
}
print "
\n";
}
}
#-----------------------------------------------------------
# ISBN変換
#-----------------------------------------------------------
sub isbn_change {
my $isbn = $_[0];
#ISBNは-を削除 x、+、*はXとみなす
$isbn =~ s/-//g;
$isbn =~ tr/+*x/X/;
return $isbn;
}
#-----------------------------------------------------------
# エラーメッセージ
#-----------------------------------------------------------
sub error {
my @msg = @_;
print "";
foreach my $i ( 0 .. $#msg ) {
print "$msg[$i]
\n";
}
print "
\n";
}