#!/usr/bin/perl

# サイト「テレビ王国」から TVscape 用番組データを取得する
# Copyleft 2006 Yoshizumi Endo <y-endo@ceres.dti.ne.jp>

# オプション:
#
# --date  取得する日付 (例: 20060301)
# --pref  取得する地域 (JIS 都道府県コード)
# --days  何日分取得するか
# --force 既に取得しているデータを再度取得する

use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request::Common qw(POST);
use Date::Simple;
use Getopt::Long;

# デフォルトの設定

$channel = 13; # 東京都
$days = 4;     # 三日分取得する

# その他グローバル変数

$data_dir = "$ENV{HOME}/.jpilot/tvscape/";
$base_url = 'http://www.so-net.ne.jp/tv/clie/tvscape/';
$data_url = "cgi-bin/getPrefProgram.cgi";
@area = ( "北海道",   "青森県",   "岩手県",   "宮城県",   "秋田県",  
	  "山形県",   "福島県",   "茨城県",   "栃木県",   "群馬県",  
	  "埼玉県",   "千葉県",   "東京都",   "神奈川県", "新潟県",  
	  "富山県",   "石川県",   "福井県",   "山梨県",   "長野県",  
	  "岐阜県",   "静岡県",   "愛知県",   "三重県",   "滋賀県",  
	  "京都府",   "大阪府",   "兵庫県",   "奈良県",   "和歌山県",
	  "鳥取県",   "島根県",   "岡山県",   "広島県",   "山口県",  
	  "徳島県",   "香川県",   "愛媛県",   "高知県",   "福岡県",  
	  "佐賀県",   "長崎県",   "熊本県",   "大分県",   "宮崎県",  
	  "鹿児島県", "沖縄県" );

# データ保管用ディレクトリのチェック

if (! -d $data_dir) {
    mkdir ($data_dir) || die "ディレクトリ $data_dir が作成できません。\n";
}

# 引数のない限りファイルの取得は一日一回に限る

if ($#ARGV < 0) {

    opendir(DIR, $data_dir);
    @dirfiles = readdir(DIR);
    closedir(DIR);

    foreach $i (@dirfiles) {

	if ($i =~ /\.pdb/) {
	    @stats = stat($data_dir . $i);

	    ($d, $m, $y,) = (localtime($stats[9]))[3, 4, 5];
	    my $file_date = sprintf("%04d-%02d-%02d\n", $y+1900, $m+1, $d);

	    if ($file_date == Date::Simple->today()) {
		exit;
	    }
	}
    }
}

# コマンドラインオプション

$opt=GetOptions(
	   'date=i' => \$date,
	   'pref=i' => \$channel,
	   'days=i' => \$days,
	   'force'  => \$force
	   );

# バナーの取得

foreach $i (1...5) {
    my $file = "TVspAD0" . $i . ".prc";
    my $url = $base_url . "banner/" . $file;
    my $rc = mirror($url, $data_dir . $file);

    if ($rc == 200 || $force) {
	push(@jp_files, $file);
    }
}

# 番組表データの取得

if ($date) {
    my $y=substr($date, 0, 4);
    my $m=substr($date, 4, 2);
    my $d=substr($date, 6, 2);
    $day = Date::Simple->new($y, $m, $d);
} else {
    $day = Date::Simple->new();
}

for ($i=0; $i<$days ; $i++) {
    my $newday = $day++;
    &get_data($newday->format("%Y%m%d"), $channel);
}

# インストール予約の重複チェック

open(JP, "$ENV{HOME}/.jpilot/jpilot_to_install");
while (<JP>) {
    chomp($_);
    push(@jp_origin, $_);
}
close(JP);

foreach $i (@jp_files) {
    if (!grep(/$i/, @jp_origin)) {
	push(@jp_install, $i);
    }
}

# インストール予約

open(JP, ">> $ENV{HOME}/.jpilot/jpilot_to_install");

foreach $i (@jp_install) {
    print JP $data_dir . $i, "\n";
}

close(JP);

# 古い番組データの削除

opendir(DIR, $data_dir);
@dirfiles = readdir(DIR);
closedir(DIR);

foreach $file (@dirfiles) {
    my $tmp = $file;

    if ($tmp =~ s/TVpg([0-9]*)-([0-9]*)-([0-9]*)-[0-9]*\.pdb/$1 $2 $3/) {
	my @fdate = split (/ /, $tmp);
	my $fdate = sprintf("%04d-%02d-%02d\n", @fdate);

	if ($fdate < Date::Simple->today()) {
	    push (@delfiles, $data_dir . $file);
	}
    }
}

if ($#delfiles+1 > 0) {
    unlink(@delfiles) || die "$! は削除できません。\n";
}

exit;

# 指定番組表データの取得

sub get_data {
    my $date = $_[0];
    my $pref =  $area[$_[1] - 1];

    my %formdata = ('date' => $date, 'pref' => $pref);
    my $request  = POST($base_url.$data_url, [%formdata]);

    my $ua = LWP::UserAgent->new;
    $ua->agent('Sony CLIE TVscape/1.0');
    my $res = $ua->request($request);

    if ($res->is_success) {
	if ($res->header('Content-Type') =~ /pdb/) {
	    my $name = substr($res->content, 0, 
			      index($res->content, "\0")) . ".pdb";
	    if (! -e $data_dir.$name  || $force) {
		open(TT, "> $data_dir$name");
		print TT $res->content;
		close (TT);
		push(@jp_files, $name);
	    }
	} else {
	    print "エラー: $date ($pref) のデータは取得できませんでした。\n";
	}
    }
    return;
}
