#!/bin/sh #from EPG xml data to iEPG # last stable version=0.2.1-pre2.3 version=0.2.2-pre7 export LANG=ja_JP.UTF-8 xml_esc() { a=${1//'&apos;'/\'} a=${a//'&amp;'/\&} a=${a//'&lt;'/\<} a=${a//'&gt;'/\>} a=${a//'&quot;'/\"} echo "$a" return 0 } sjsafe() { echo "$1" |iconv -f UTF-8 -t $iepg_charset >/dev/null 2>&1 ;iv=$? if [ $iv = 0 ]; then xml_esc "$1" return 0 fi sjf_list="Ⅰ Ⅱ Ⅲ Ⅳ Ⅴ Ⅵ Ⅶ Ⅷ Ⅸ Ⅹ ① ② ③ ④ ⑤ ⑥ ⑦ ⑪ - ⁉" sjf_sub=(I II III IV V VI VII VIII IX X \(1\) \(2\) \(3\) \(4\) \(5\) \(6\) \(7\) \(11\) ‐ !?) s_str="" n=0 while [ "${1:$n:1}" ]; do c="${1:$n:1}" i=0 sj_ok=1 for s in $sjf_list ; do if [ "$s" = "$c" ]; then s_str="$s_str${sjf_sub[$i]}" sj_ok=0 break fi i=$(($i+1)) done if [ $sj_ok = 1 ]; then echo "$c" |iconv -f UTF-8 -t $iepg_charset >/dev/null 2>&1 ;iv=$? if [ $iv = 0 ]; then s_str="$s_str$c" else s_str="${s_str}?" fi fi n=$(($n+1)) done xml_esc "$s_str" return 0 } genre_db="16:1:スポーツ:sports:野球:16:1:101000:101101 16:2:スポーツ:sports:サッカー:16:2:101000:101102 16:3:スポーツ:sports:ゴルフ:16:3:101000:101103 16:4:スポーツ:sports:その他の球技:16:4:101000:101104 16:5:スポーツ:sports:マリン・ウインタースポーツ:16:5:101000:101109 16:5:スポーツ:sports:マリン・ウィンタースポーツ:16:5:101000:101109 16:6:スポーツ:sports:モータースポーツ:16:6:101000:101108 16:8:スポーツ:sports:相撲・格闘技:16:8:101000:101105 16:16:スポーツ:sports:オリンピック・国際大会:16:16:101000:101106 16:53:スポーツ:sports:競馬・公営競技:16:53:101000:101110 16:144:スポーツ:sports:マラソン・陸上・水泳:16:144:101000:101107 69:6:スポーツ:sports:スポーツニュース:69:6:101000:101100 16:144:スポーツ:sports:その他:16:144:101000:101115 32:2:音楽:music:国内ロック・ポップス:32:2:104000:104100 32:3:音楽:music:海外ロック・ポップス:32:3:104000:104101 32:5:音楽:music:クラシック・オペラ:32:5:104000:104102 32:6:音楽:music:歌謡曲・演歌:32:6:104000:104104 32:7:音楽:music:民謡・邦楽:32:7:104000:104108 32:8:音楽:music:ライブ・コンサート:32:8:104000:104105 32:9:音楽:music:ランキング・リクエスト:32:9:104000:104106 32:16:音楽:music:カラオケ・のど自慢:32:16:104000:104107 32:17:音楽:music:童謡・キッズ:32:17:104000:104109 32:144:音楽:music:ジャズ・フュージョン:32:144:104000:104103 32:144:音楽:music:民族音楽・ワールドミュージック:32:144:104000:104110 32:144:音楽:music:その他:32:144:104000:104115 48:1:ドラマ:drama:国内ドラマ:48:1:103000:103100 48:2:ドラマ:drama:時代劇:48:2:103000:103102 48:3:ドラマ:drama:海外ドラマ:48:3:103000:103101 48:144:ドラマ:drama:その他:48:144:103000:103115 53:2:劇場/公演:stage:歌舞伎・古典:53:2:109000:109104 53:3:劇場/公演:stage:ミュージカル:53:3:109000:109101 53:4:劇場/公演:stage:落語・演芸:53:4:109000:109103 53:144:劇場/公演:stage:現代劇・新劇:53:144:109000:109100 53:144:劇場/公演:stage:ダンス・バレエ:53:144:109000:109102 53:144:劇場/公演:stage:その他:53:144:109000:109115 64:1:ドキュメンタリー/教養:documentary:社会・時事:64:1:108000:108100 64:2:ドキュメンタリー/教養:documentary:カルチャー・伝統文化:64:2:108000:108104 64:2:ドキュメンタリー/教養:documentary:文学・文芸:64:2:108000:108105 64:3:ドキュメンタリー/教養:documentary:自然・動物・環境:64:3:108000:108102 64:4:ドキュメンタリー/教養:documentary:スポーツ:64:4:108000:108106 64:5:ドキュメンタリー/教養:documentary:歴史・紀行:64:5:108000:108101 64:6:ドキュメンタリー/教養:documentary:宇宙・科学・医学:64:6:108000:108103 64:144:ドキュメンタリー/教養:documentary:インタビュー・討論:64:144:108000:108108 64:144:ドキュメンタリー/教養:documentary:ドキュメンタリー全般:64:144:108000:108107 64:144:ドキュメンタリー/教養:documentary:その他:64:144:108000:108115 69:1:ニュース/報道:news:定時・総合:69:1:100000:100100 69:2:ニュース/報道:news:ローカル・地域:69:2:100000:100109 69:3:ニュース/報道:news:海外・国際:69:3:100000:100105 69:4:ニュース/報道:news:経済・市況:69:4:100000:100104 69:7:ニュース/報道:news:天気:69:7:100000:100101 69:8:ニュース/報道:news:政治・国会:69:8:100000:100103 69:9:ニュース/報道:news:討論・会談:69:9:100000:100107 69:9:ニュース/報道:news:特集・ドキュメント:69:9:100000:100102 69:10:ニュース/報道:news:解説:69:10:100000:100106 69:144:ニュース/報道:news:報道特番:69:144:100000:100108 69:144:ニュース/報道:news:交通:69:144:100000:100110 69:144:ニュース/報道:news:その他:69:144:100000:100115 80:1:映画:cinema:邦画:80:1:106000:106101 80:2:映画:cinema:アニメ:80:2:106000:106102 80:3:映画:cinema:洋画:80:3:10600:106100 80:144:映画:cinema:その他:80:144:10600:106115 96:2:バラエティー:variety:お笑い・コメディ:96:2:105000:105103 96:3:バラエティー:variety:トークバラエティ:96:3:105000:105102 96:5:バラエティー:variety:クイズ:96:5:105000:105100 96:5:バラエティー:variety:ゲーム:96:5:105000:105101 32:1:バラエティー:variety:音楽バラエティ:32:1:105000:105104 96:6:バラエティー:variety:旅バラエティ:96:6:105000:105105 96:7:バラエティー:variety:料理バラエティ:96:7:105000:105106 96:144:バラエティー:variety:その他:96:144:105000:105115 112:1:アニメ/特撮:anime:国内アニメ:112:1:107000:107100 112:2:アニメ/特撮:anime:海外アニメ:112:2:107000:107101 112:3:アニメ/特撮:anime:特撮:112:3:107000:107102 112:144:アニメ/特撮:anime:その他:112:144:107000:107115 128:2:趣味/教育:hobby:旅・釣り・アウトドア:128:2:110000:110100 128:3:趣味/教育:hobby:車・オートバイ:128:3:110000:110105 128:4:趣味/教育:hobby:園芸・ペット・手芸:128:4:110000:110101 128:5:趣味/教育:hobby:囲碁・将棋:128:5:110000:110103 128:7:趣味/教育:hobby:会話・語学:128:7:110000:110107 128:8:趣味/教育:hobby:コンピュータ・TVゲーム:128:8:110000:110106 128:18:趣味/教育:hobby:音楽・美術・工芸:128:18:110000:110102 128:144:趣味/教育:hobby:麻雀・パチンコ:128:144:110000:110104 133:1:趣味/教育:hobby:幼児・小学生:133:1:110000:110108 133:2:趣味/教育:hobby:中学生・高校生:133:2:110000:110109 133:4:趣味/教育:hobby:生涯教育・資格:133:4:110000:110111 133:144:趣味/教育:hobby:教育問題:133:144:110000:110112 133:144:趣味/教育:hobby:大学生・受験:133:144:110000:110110 133:144:趣味/教育:hobby:その他:133:144:110000:110115 144:1:情報/ワイドショー:information:ショッピング・通販:144:1:102000:102104 144:2:情報/ワイドショー:information:芸能・ワイドショー:144:2:102000:102100 144:3:情報/ワイドショー:information:番組紹介・お知らせ:144:3:102000:102107 144:4:情報/ワイドショー:information:イベント:144:4:102000:102106 144:8:情報/ワイドショー:information:グルメ・料理:144:8:102000:102105 144:9:情報/ワイドショー:information:ファッション:144:9:102000:102101 144:16:情報/ワイドショー:information:暮らし・住まい:144:16:102000:102102 144:17:情報/ワイドショー:information:健康・医療:144:17:102000:102103 144:144:情報/ワイドショー:information:その他:144:144:102000:102115 160:1:福祉:welfare:音声解説:160:1:111000:111106 160:1:福祉:welfare:高齢者:160:1:111000:111100 160:1:福祉:welfare:社会福祉:160:1:111000:111102 160:1:福祉:welfare:手話:160:1:111000:111104 160:1:福祉:welfare:障害者:160:1:111000:111101 160:144:福祉:welfare:ボランティア:160:144:111000:111103 160:144:福祉:welfare:文字(字幕):160:144:111000:111105 160:144:福祉:welfare:その他:160:144:111000:111115 153:144:その他:Other:その他:153:144:115000:115115 " check_epg_xml() { epg_ch_id=`grep '<channel id="' $1 |cut -d'"' -f2` epg_ch_type=`echo "$epg_ch_id" |head -n 1` if [ "${epg_ch_id:0:2}" = GR ]; then if [ "$2" ];then check_st_id=${2:1:1} if [ $check_st_id = 0 ]; then check_regx=_${2:2} else check_regx=_${2:1} fi echo "$epg_ch_id" |grep $check_regx else echo "$epg_ch_id" fi rv=0 elif [ "${epg_ch_id:0:2}" = BS ]; then echo "$epg_ch_id" |grep _${2:3:3} rv=0 else if [ "${epg_ch_type//[0-9]/}" ]; then if [ "$2" ]; then echo 4${2:3:3}.epgdata.ontvjapan else echo "$epg_ch_id" fi else echo $epg_ch_type fi rv=1 fi return $rv } if [ -f /etc/iepgd.conf ]; then . /etc/iepgd.conf fi if [ -f .iepgd.conf ]; then . $PWD/.iepgd.conf fi is_root=${is_root:-/var/www/html/} st_id_list=${st_id_list:-$is_root/STATION.ID} org_charset=shift_jis iepg_charset=${iepg_charset:-$org_charset} xml_type=0 if [ "$QUERY_STRING" ]; then iepg_id=${QUERY_STRING#id=} else iepg_id=$1 fi st_id_iepg=${iepg_id:0:6} st_id_iepg_x="" pref_id=`grep ^$st_id_iepg: $st_id_list |cut -d':' -f4` if [ "$pref_id" ]; then if [ $pref_id = 1 ]; then pref_id=23 elif [ $pref_id = 2 ]; then pref_id=40 elif [ $pref_id = 3 ]; then pref_id=33 elif [ $pref_id = 4 ]; then pref_id=10 elif [ $pref_id = 5 ]; then pref_id=45 elif [ $pref_id = 6 ]; then pref_id=48 fi xml_dir=$is_root/pref.$pref_id if [ -d $xml_dir ]; then pref_id_err=0 else pref_id_err=1 fi else if [ ${st_id_iepg:0:1} = 1 ]; then if [ ${st_id_iepg:1:1} = 0 ]; then st_id_regx=_${st_id_iepg:2} else st_id_regx=_${st_id_iepg:1} fi st_id_Ym=${iepg_id:6:6} for t in `ls -d $is_root/pref.[!b]*` ; do for td in `ls -r $t 2>/dev/null |grep -m 10 .xml` ; do td_xml=$t/$td if [ ! -f $td_xml ]; then continue fi grv=`grep -m1 -A1 '<chann.*'$st_id_regx $td_xml 2>&1 |tail -1` if [ "$grv" ]; then tt=${td%.xml} st_id_iepg_x=${tt##*.} st_name_x=${grv#*\>} st_name_x=${st_name_x%\<*} break fi done if [ "$st_id_iepg_x" ]; then xml_dir=${td_xml%/*} pref_id=${xml_dir##*.} pref_id_err=0 break fi done elif [ ${st_id_iepg:0:1} = 2 ]; then for t in $is_root/pref.bs[1234] ;do grep :${st_id_iepg%?} $t/ch.list.${t##*.} >/dev/null 2>&1 ;gv=$? if [ $gv = 0 ]; then st_id_iepg_x=bs xml_dir=$t pref_id=${t##*.} st_name_x=BSDT${st_id_iepg:3} pref_id_err=0 break fi done fi if [ ! "$st_id_iepg_x" ]; then pref_id_err=2 fi fi id_err=0 admin_v=0 if [ "${iepg_id//[0-9]/}" ]||[ ${#iepg_id} != 18 ]||[ $pref_id_err != 0 ]; then err_title="iEPG error" err_pref="iEPG error occured" if [ "$iepg_id" ]; then if [ "${iepg_id//[0-9]/}" ]; then if [ "$iepg_id" = admin ]; then err_title="administrator mode" err_pref="iepgd.cgi outputs environment variables" err_re="$err_title<br><pre>`export`</pre>" admin_v=1 else id_err=1 err_re="invalid value" fi err_re="$iepg_id, $err_re" else id_err=2 if [ ${#iepg_id} -gt 18 ]; then err_re="$iepg_id, value too long" elif [ ${#iepg_id} -lt 18 ]; then err_re="$iepg_id, value too short" elif [ $pref_id_err = 1 ]; then err_re="${iepg_id:0:6}, this station ID is unsupported" elif [ $pref_id_err = 2 ]; then err_re="${iepg_id:0:6}, unknown station ID" else err_re="${iepg_id:0:6}, unknown error" fi fi else id_err=3 err_re="value not set" fi if [ $admin_v = 0 ]; then echo "$err_re" >&2 fi ex_YmdHM=`date '+%Y-%m-%d %H:%M'` err_mesg="<!DOCTYPE html>\r\n<html><head><title>$err_title</title></head>" err_mesg=$err_mesg"<body>\r\n$ex_YmdHM: $err_pref<br>\r\n" err_mesg=$err_mesg"REMOTE_ADDR=$REMOTE_ADDR:iepg_id=$iepg_id<br>\r\n" err_mesg=$err_mesg"$err_re<br>\r\n<br>\r\n" err_mesg=$err_mesg"${0##*/}-$version</body></html>\r\n" content_length_wc=`echo -ne "$err_mesg" |wc -c` echo -ne "Content-Length: $content_length_wc\r\n" echo -ne "Connction: close\r\n" echo -ne "Content-type: text/html\r\n\r\n" echo -ne "$err_mesg" exit $id_err fi rqs_st=${iepg_id:6:12} rqs_Ymd=${rqs_st:0:8} if [ "$st_id_iepg_x" ]; then sc=$st_id_iepg_x elif [ ${st_id_iepg:0:1} = 1 ]; then sc=$st_id_iepg elif [ ${st_id_iepg:0:1} = 2 ]; then st_id_xbs=4${st_id_iepg:3:3} sc=bs else sc=$st_id_iepg fi all_xml=`echo $xml_dir/epg.*.$sc.xml` last_xml=${all_xml##* } ch_ext=`check_epg_xml $last_xml $st_id_iepg` last_p=`grep \<prog.*channel=\"${ch_ext} $last_xml |tail -1` last_date=${last_p#*stop=\"} last_date=${last_date%% *} last_YmdHM=${last_date:0:12} first_xml=${all_xml%% *} ch_ext=`check_epg_xml $first_xml $st_id_iepg` first_p=`grep -m 1 \<prog.*channel=\"${ch_ext} $first_xml` if [ "$first_p" ]; then first_date=${first_p#*start=\"} first_date=${first_date%% *} first_YmdHM=${first_date:0:12} else first_ch_list_data=`grep :$st_id_iepg: $xml_dir/ch.list.$pref_id.* 2>/dev/null |head -n 1` if [ "$first_ch_list_data" ]; then first_ch_list=${first_ch_list_data%%:*} first_ch_list_date=${first_ch_list##*.} first_YmdHM=${first_ch_list_date}0400 else first_YmdHM=$rqs_st fi fi xml_ok=0 epg_ok=0 st_id_ok=0 exp_err=0 if [ $rqs_st -lt $first_YmdHM ]; then org_xml="${first_xml##*/}" exp_err=1 elif [ $rqs_st -ge $last_YmdHM ]; then org_xml="${last_xml##*/}" exp_err=2 else out_Ymd=`date -d "-10day $rqs_Ymd" '+%Y%m%d'` xml_list=`ls -r $xml_dir/epg.*.$sc.xml 2>/dev/null |grep -B 20 epg.$out_Ymd.*.$sc.xml` if [ ! "$xml_list" ]; then for t in `ls -r $xml_dir/epg.*.$sc.xml 2>/dev/null |cut -d'.' -f3` ; do check_Ymd=${t:0:8} if [ $check_Ymd -lt $out_Ymd ]; then out_Ymd=$check_Ymd break fi done xml_list=`ls -r $xml_dir/epg.*.$sc.xml 2>/dev/null |grep -B 10 epg.$out_Ymd.*.$sc.xml` if [ ! "$xml_list" ]; then xml_list=`ls -r $xml_dir/epg.*.$sc.xml 2>/dev/null` fi fi for t in $xml_list ; do ch_ext=`check_epg_xml $t $st_id_iepg` first_p=`grep -m 1 programme.*start.*$ch_ext $t` last_p=`grep programme.*start.*$ch_ext $t |tail -1` first_date=${first_p#*start=\"} first_date=${first_date%% *} first_YmdHM=${first_date:0:12} last_date=${last_p#*stop=\"} last_date=${last_date%% *} last_YmdHM=${last_date:0:12} if [ $rqs_st -ge $first_YmdHM ]&&[ $rqs_st -lt $last_YmdHM ]; then org_xml=$t xml_ok=1 break fi done match_ok=0 prog_genre="" prog_genre_middle="" while read t ; do st_id_ok=1 epg_st=${t#*\"} epg_st=${epg_st%% *} epg_et=${t#*stop=\"} epg_et=${epg_et%% *} if [ ${epg_st:-0} -le ${rqs_st}00 ]&&[ ${rqs_st}00 -lt ${epg_et:-0} ]; then ex_prog_YmdHM=${epg_st:0:12} end_YmdHM=${epg_et:0:12} l_num=${t%%:*} match_ok=1 epg_ok=1 if [ "${ch_ext:0:2}" = GR ]||[ "${ch_ext:0:2}" = BS ]; then xml_type=1 fi while read s ; do check_tag=${s#*\<} check_tag=${check_tag%%\>*} if [ "$check_tag" = 'title lang="ja_JP"' ]; then prog_title=${s#*\>} prog_title=${prog_title%\<*} prog_title=`sjsafe "$prog_title"` continue fi if [ "$check_tag" = 'category lang="en"' ]&&[ ! "$prog_genre" ]; then prog_genre=${s#*\>} prog_genre=${prog_genre%\<*} continue fi if [ "$check_tag" = 'category_middle lang="ja_JP"' ]&&[ ! "$prog_genre_middle" ]; then prog_genre_middle=${s#*\>} prog_genre_middle=${prog_genre_middle%\<*} continue fi if [ "$check_tag" = 'desc lang="ja_JP"' ]; then abs_data=${s#*\>} abs_data=${abs_data%\<*} abs_data=`sjsafe "$abs_data"` continue fi if [ "$check_tag" = '/programme' ]; then break fi done <<EOF_pdt8H `tail -n +$(($l_num+1)) $org_xml` EOF_pdt8H break fi done <<EOF_jTf55 `grep -n \<prog.*channel=\"${ch_ext} $org_xml` EOF_jTf55 fi if [ $epg_ok = 0 ];then if [ $exp_err = 1 ];then err_re="${iepg_id:6:12}, program before $first_YmdHM" elif [ $exp_err = 2 ];then err_re="${iepg_id:6:12}, program after $last_YmdHM" else if [ $xml_ok = 0 ];then err_re="xml file not found" else if [ $st_id_ok = 0 ];then err_re="$st_id_iepg unknown station ID" else epg_ok=2 err_re="EPG data not found" while read t ;do st_id_ok=1 epg_st=${t#*\"} epg_st=${epg_st%% *} epg_et=${t#*stop=\"} epg_et=${epg_et%% *} if [ ${epg_et:-0} -ge ${rqs_st}00 ];then err_start_date=$epg_st break fi done <<EOF_iepg_54812 `grep \<prog.*channel=\"${ch_ext} $org_xml` EOF_iepg_54812 while read t ;do st_id_ok=1 epg_st=${t#*\"} epg_st=${epg_st%% *} epg_et=${t#*stop=\"} epg_et=${epg_et%% *} if [ ${epg_st:-0} -lt ${rqs_st}00 ];then err_end_date=$epg_et break fi done <<EOF_iepg_54812 `tac $org_xml |grep \<prog.*channel=\"${ch_ext}` EOF_iepg_54812 ex_prog_YmdHM=$err_start_date end_YmdHM=$err_end_date prog_title="unknown program" abs_data="$err_re" fi fi fi fi if [ $epg_ok = 0 ];then ex_YmdHM=`date '+%Y-%m-%d %H:%M'` err_mesg="$ex_YmdHM: iEPG error occured. $err_re<br>\r\n\ REMOTE_ADDR=$REMOTE_ADDR:iepg_id=$iepg_id<br>\r\n\ st_id_iepg=$st_id_iepg: $first_YmdHM - $last_YmdHM: st_id_ok=$st_id_ok<br>\r\n\ xml_ok=$xml_ok: org_xml=$org_xml: epg_ok=$epg_ok\r\n iepgd.cgi-$version\r\n" err_return="<!DOCTYPE html>\r\n <html><head><title>iEPG error</title></head><body>\r\n $err_mesg</body></html>\r\n" content_length_wc=`echo -ne "$err_return" |wc -c` echo -ne "Content-Length: $content_length_wc\r\n" echo -ne "Connction: close\r\n" echo -ne "Content-type: text/html\r\n\r\n" echo -ne "$err_return" exit 1 fi ############### iepg return ############### if [ "$st_id_iepg_x" ]; then iepg_st_id=$st_name_x else iepg_st_id=`grep $st_id_iepg $st_id_list |cut -d':' -f3` iepg_st_id=${iepg_st_id#*:} fi if [ $epg_ok = 1 ]; then if [ $xml_type = 1 ]; then if [ "$prog_genre" ];then prog_genre_id=`echo "$genre_db" |grep -m 1 $prog_genre:$prog_genre_middle:` genre_id=${prog_genre_id%%:*} genre_id=${genre_id:-153} if [ "$prog_genre_middle" ]; then subgenre_id=${prog_genre_id#*:} subgenre_id=${subgenre_id%%:*} genre_id=${genre_id:-153} subgenre_id=${subgenre_id:-144} else subgenre_id=144 fi else genre_id=153 subgenre_id=144 fi else prog_genre_id=`echo "$genre_db" |grep -m 1 :$prog_genre:` genre_id=${prog_genre_id%%:*} subgenre_id="" fi else genre_id=153 subgenre_id=144 fi iepg_return="Content-type: application/x-tv-program-info; charset=$org_charset\r\n\ version: 1\r\n\ station: $iepg_st_id\r\n\ year: ${ex_prog_YmdHM:0:4}\r\n\ month: ${ex_prog_YmdHM:4:2}\r\n\ date: ${ex_prog_YmdHM:6:2}\r\n\ start: ${ex_prog_YmdHM:8:2}:${ex_prog_YmdHM:10:2}\r\n\ end: ${end_YmdHM:8:2}:${end_YmdHM:10:2}\r\n\ program-title: $prog_title\r\n\ genre: ${genre_id:-153}\r\n\ subgenre: ${subgenre_id}\r\n\ \r\n\ $abs_data" content_length_wc=`echo -ne "$iepg_return" |iconv -f utf-8 -t $iepg_charset |wc -c` echo -ne "Content-Length: $content_length_wc\r\n" echo -ne "Connection: close\r\n" echo -ne "Content-type: application/x-tv-program-info; charset=$iepg_charset\r\n\r\n" echo -ne "$iepg_return" |iconv -f utf-8 -t $iepg_charset exit 0 --- txt.cgi-0.1.5