#!/usr/bin/perl
#--------------------------------------------------------------
#
# 楽天商品検索APIの利用サンプルコード (Perl)
# appバージョン 2014-02-22
#
#--------------------------------------------------------------
# テストプログラム - https://webservice.rakuten.co.jp/explorer/api/

print "Content-type: text/html; charset=UTF-8\n\n";

#---------------- 以下、変更部分 ------------------------------

# 自分のディベロッパーID
$APP_ID = "ここにディベロッパーIDを記入する";

# 自分のアフィリエイトID
$AFFILIATE_ID = "ここにアフィリエイトIDを記入する";

#---------------- 以上、変更部分 ------------------------------

# API名
$API_NAME       = "楽天商品検索API";

# APIのURL
$API_BASE_URL   = "https://app.rakuten.co.jp/services/api/IchibaItem/Search/20140222";

# APIのタイプ
$OPERATION      = "ItemSearch";

# APIのバージョン
$API_VERSION    = "2014-02-22";

#--------------------------------------------------------------
# メイン処理
#--------------------------------------------------------------
use LWP::Simple;
use URI::Escape;
use Jcode;

# APIへのパラメタの連想配列
# 詳しくは、https://webservice.rakuten.co.jp/api/ichibaitemsearch/ を参照
my %api_params          = (
    "format"                  => "xml",
    "keyword"                 => "%e3%83%91%e3%82%bd%e3%82%b3%e3%83%b3",
    "shopCode"                => "",
    "itemCode"                => "",
    "genreId"                 => "",
    "tagId"                   => "",
    "hits"                    => "3",
    "page"                    => "",
    "sort"                    => "%2dreviewCount",
    "minPrice"                => "",
    "maxPrice"                => "",
    "availability"            => "",
    "field"                   => "",
    "carrier"                 => "",
    "imageFlag"               => "",
    "orFlag"                  => "",
    "NGKeyword"               => "",
    "purchaseType"            => "",
    "shipOverseasFlag"        => "",
    "shipOverseasArea"        => "",
    "asurakuFlag"             => "",
    "asurakuArea"             => "",
    "pointRateFlag"           => "",
    "pointRate"               => "",
    "postageFlag"             => "",
    "creditCardFlag"          => "",
    "giftFlag"                => "",
    "hasReviewFlag"           => "",
    "maxAffiliateRate"        => "",
    "minAffiliateRate"        => "",
    "hasMovieFlag"            => "",
    "pamphletFlag"            => "",
    "appointDeliveryDateFlag" => "",
    "genreInformationFlag"    => "",
    "tagInformationFlag"      => ""
);

#--------------------------------------------------------------
# フォーム値からのパラメタ取得
#--------------------------------------------------------------
# リクエストURL生成
my $api_url = sprintf("%s?applicationId=%s&affiliateId=%s",$API_BASE_URL,$APP_ID,$AFFILIATE_ID);

# GETメソッドの場合
if( $ENV{'REQUEST_METHOD'} eq "GET" ) {
$buffer = $ENV{'QUERY_STRING'};
# POSTメソッドの場合
} else {
  read( STDIN, $buffer, $ENV{'CONTENT_LENGTH'} );
}

# リクエストパラメタを連想配列に入れる
my %req_params = map { /([^=]+)=(.+)/ } split /&/, $buffer;

# APIのクエリ生成
while ( ( $key, $value ) = each ( %api_params ) ) {

	# リクエストパラメーターの挿入
	if($req_params{$key}){
		$api_url = sprintf("%s&%s=%s",$api_url, $key, $req_params{$key});
	# APIパラメーターの挿入
	} elsif($api_params{$key}) {
		$api_url = sprintf("%s&%s=%s",$api_url, $key, $api_params{$key});
	}
}

#--------------------------------------------------------------
# ウェブサービスAPIに問合せ
#--------------------------------------------------------------
my $data = get($api_url);

#--------------------------------------------------------------
# パース処理
#--------------------------------------------------------------
my ($count,$page,$first,$last,$carrier,$pageCount,@items);
# 必要な情報だけ簡易な正規表現で取得
if($data){
	$data =~s/\n//g;
	# 索結果の総商品数
	if($data =~/<count>(.+)<\/count>/){
		$count = $1;
	}
	# 現在のページ番号
	if($data =~/<page>(.+)<\/page>/){
		$page = $1;
	}
	# 検索結果の何件目からか
	if($data =~/<first>(.+)<\/first>/){
		$first = $1;
	}
	# 検索結果の何件目までか
	if($data =~/<last>(.+)<\/last>/){
		$last = $1;
	}
	# キャリア情報(PC=0 or mobile=1 or smartphone=2)
	if($data =~/<carrier>(.+)<\/carrier>/){
		$carrier = $1;
	}
	# 総ページ数(最大100)
	if($data =~/<pageCount>(.+)<\/pageCount>/){
		$pageCount = $1;
	}
	# 商品情報
	if($data =~/<Items>(.+)<\/Items>/){
		@items = split(/<\/Item>/,$1); 
	}
} else {
	# データが無い時は強制終了
   	exit 1;
	}
#}

#--------------------------------------------------------------
# アイテムのパース処理
#--------------------------------------------------------------
my ($write_day,$write_body);
$write_body = "<div>";

# ベタな正規表現
foreach my $item ( @items ){
	my ($itemName,$catchcopy,$itemCode,$itemPprice,$itemCaption,$itemUr,$affiliateurl,$imageFlag,$mediumImageUrls,@medium_images,$smallImageUrls,@small_images,$availability,$taxFlag,$postageFlag,$creditCardFlag,$shopOfTheYearFlag,$shipOverseasFlag,$shipOverseasArea,$asurakuFlag,$asurakuClosingTime,$asurakuArea,$affiliateRate,$startTime,$endTime,$reviewCount,$reviewAverage,$pointRate,$pointRateStartTime,$pointRateEndTime,$giftFlag,$shopname,$shopCode,$shopurl,$shopAffiliateUrl,$genreId,$tagIds,$GenreInformation,$TagInformation);
	if ($item=~/<itemName>(.+)<\/itemName>/) 			{ $itemName=$1; }				#商品名
	if ($item=~/<catchcopy>(.+)<\/catchcopy>/)			{ $catchcopy = $1; }				#キャッチコピー
	if ($item=~/<itemCode>(.+)<\/itemCode>/)			{ $itemCode = $1; }				#商品コード
	if ($item=~/<itemPrice>(.+)<\/itemPrice>/)			{ $itemPprice = $1; }				#商品価格
	if ($item=~/<itemCaption>(.+)<\/itemCaption>/)			{ $itemCaption = $1; }				#商品説明文
	if ($item=~/<itemUrl>(.+)<\/itemUrl>/)				{ $itemUrl = $1; }				#商品URL
	if ($item=~/<affiliateUrl>(.+)<\/affiliateUrl>/)		{ $affiliateurl = $1; }				#アフィリエイトURL
	if ($item=~/<imageFlag>(.+)<\/imageFlag>/)			{ $imageFlag = $1; }				#商品画像有無フラグ
	if ($item=~/<mediumImageUrls>(.+)<\/mediumImageUrls>/)		{ $mediumImageUrls = $1; }			#商品画像128x128URL
	if ($mediumImageUrls=~/<imageUrl>(.+)<\/imageUrl>/)		{ @medium_images = split(/<\/imageUrl>/,$1); }
	if ($item=~/<smallImageUrls>(.+)<\/smallImageUrls>/)		{ $smallImageUrls = $1; }			#商品画像64x64URL
	if ($smallImageUrls=~/<imageUrl>(.+)<\/imageUrl>/)		{ @small_images = split(/<\/imageUrl>/,$1); }
	if ($item=~/<availability>(.+)<\/availability>/)		{ $availability = $1; }				#販売可能フラグ
	if ($item=~/<taxFlag>(.+)<\/taxFlag>/)				{ $taxFlag = $1; }				#消費税フラグ
	if ($item=~/<postageFlag>(.+)<\/postageFlag>/)			{ $postageFlag = $1; }				#送料フラグ
	if ($item=~/<creditCardFlag>(.+)<\/creditCardFlag>/)		{ $creditCardFlag = $1; }			#クレジットカード利用可能フラグ
	if ($item=~/<shopOfTheYearFlag>(.+)<\/shopOfTheYearFlag>/)	{ $shopOfTheYearFlag = $1; }			#ショップオブザイヤーフラグ
	if ($item=~/<shipOverseasFlag>(.+)<\/shipOverseasFlag>/)	{ $shipOverseasFlag = $1; }			#海外配送フラグ 
	if ($item=~/<shipOverseasArea>(.+)<\/shipOverseasArea>/)	{ $shipOverseasArea = $1; }			#海外配送対象地域
	if ($item=~/<asurakuFlag>(.+)<\/asurakuFlag>/)			{ $asurakuFlag = $1; }				#あす楽フラグ
	if ($item=~/<asurakuClosingTime>(.+)<\/asurakuClosingTime>/)	{ $asurakuClosingTime = $1; }			#あす楽〆時間
	if ($item=~/<asurakuArea>(.+)<\/asurakuArea>/)			{ $asurakuArea = $1; }				#あす楽配送対象地域
	if ($item=~/<affiliateRate>(.+)<\/affiliateRate>/)		{ $affiliateRate = $1; }			#アフィリエイト利用利率
	if ($item=~/<startTime>(.+)<\/startTime>/)			{ $startTime = $1; }				#販売開始時刻
	if ($item=~/<endTime>(.+)<\/endTime>/)				{ $endTime = $1; }				#販売終了時刻
	if ($item=~/<reviewCount>(.+)<\/reviewCount>/)			{ $reviewCount = $1; }				#レビュー件数
	if ($item=~/<reviewAverage>(.+)<\/reviewAverage>/)		{ $reviewAverage = $1; }			#レビュー平均
	if ($item=~/<pointRate>(.+)<\/pointRate>/)			{ $pointRate = $1; }				#商品別ポイント倍付け
	if ($item=~/<pointRateStartTime>(.+)<\/pointRateStartTime>/)	{ $pointRateStartTime = $1; }			#商品別ポイント倍付け開始日時
	if ($item=~/<pointRateEndTime>(.+)<\/pointRateEndTime>/)	{ $pointRateEndTime = $1; }			#商品別ポイント倍付け終了日時
	if ($item=~/<giftFlag>(.+)<\/giftFlag>/)			{ $giftFlag = $1; }				#ギフト包装フラグ
	if ($item=~/<shopName>(.+)<\/shopName>/)			{ $shopname =$1; }				#店舗名
	if ($item=~/<shopCode>(.+)<\/shopCode>/)			{ $shopCode = $1; }				#店舗コード
	if ($item=~/<shopUrl>(.+)<\/shopUrl>/)				{ $shopurl =$1; } 				#店舗URL
	if ($item=~/<shopAffiliateUrl>(.+)<\/shopAffiliateUrl>/)	{ $shopAffiliateUrl = $1; }			#店舗アフィリエイトURL
	if ($item=~/<genreId>(.+)<\/genreId>/)				{ $genreId = $1; }				#ジャンルID
	if ($item=~/<tagIds>(.+)<\/tagIds>/)				{ $tagIds = $1; }				#タグ情報
	if ($item=~/<GenreInformation>(.+)<\/GenreInformation>/)	{ $GenreInformation = $1; }			#ジャンルごとの商品数
	if ($item=~/<TagInformation>(.+)<\/TagInformation>/)		{ $TagInformation = $1; }			#タグごとの商品数

	# 1個しか表示させない時のゴミ対策
	if ($itemName) {
		# アフィリエイトコードを短く
		my $short_itemName = Encode::encode_utf8(substr(Encode::decode_utf8($itemName), 0, 30));
	$write_body = $write_body."<p><a href=\"$affiliateurl\"><img src=\"$medium_images[0]\">$short_itemName</a></p>";
	}
}

$write_body = $write_body."</div>";

#--------------------------------------------------------------
# キャッシュファイルの書き込み
#--------------------------------------------------------------
# エスケープ処理
$write_body = &htmlspecialchars($write_body);

# アフィリエイトコード表示
print "document.write('$write_body')";

exit 0;

#--------------------------------------------------------------
# タグ処理
#--------------------------------------------------------------
sub tagescape {
	my $value = shift;
	# タグ処理
	$value =~ s/&/&amp;/g;
	$value =~ s/"/&quot;/g;

	# 改行処理
	$value =~ s/</&lt;/g;
	$value =~ s/>/&gt;/g;
	return $value;
}

#--------------------------------------------------------------
# 文字列をエスケープ
#--------------------------------------------------------------
sub htmlspecialchars {
	my $str = shift;
	$str =~ s/&/&amp;/g;
	$str =~ s/"/\"/g;
	$str =~ s/'/\&\#39\;/g;
	$str =~ s/</\</g;
	$str =~ s/>/\>/g;
	return $str;
}