changeset 87:36ac7c416bd7

merged with upstream
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 01 Mar 2010 20:51:36 +0900
parents 11f63ae04a96 (current diff) c29d41d0c945 (diff)
children 3941ee5b3e63
files Reservation.class.php Settings.class.php do-record.sh.pt1 epgrec_upgrade.php getepg.php simpleReservation.php
diffstat 25 files changed, 1078 insertions(+), 267 deletions(-) [+]
line wrap: on
line diff
--- a/Keyword.class.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/Keyword.class.php	Mon Mar 01 20:51:36 2010 +0900
@@ -43,6 +43,10 @@
 			$options .= " AND channel_id = '".$this->channel_id."'";
 		}
 		
+		if( $this->weekofday != 7 ) {
+			$options .= " AND WEEKDAY(starttime) = '".$this->weekofday."'";
+		}
+		
 		$options .= " ORDER BY starttime ASC";
 		
 		$recs = array();
@@ -72,7 +76,7 @@
 			foreach( $precs as $rec ) {
 				try {
 					if( $rec->autorec ) {
-						Reservation::simple( $rec->id, $this->id, $this->settings->autorec_mode );
+						Reservation::simple( $rec->id, $this->id, $this->autorec_mode );
 						usleep( 100 );		// あんまり時間を空けないのもどう?
 					}
 				}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.ja	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,165 @@
+epgrecは日本のデジタル放送用録画システムです。
+
+●改造のための情報
+
+ ファイルが増えてきたので整理をかねてメモを記しておきます。
+
+■DBRecordクラス
+
+ epgrecは簡易O/Rマッピングを行うDBRecordクラスを足回りとして利用しています。
+
+・オブジェクトの作成
+$record = new DBRecord( PROGRAM_TBL|CATEGORY_TBL|CHANNEL_TBL|KEYWORD_TBL|RESERVE_TBL
+                        [,フィールド名 ,検索語句]
+);
+
+ DBレコードに関連づけられたDBRecordオブジェクトを生成します。フィールド名と検索語句を指定すると、DBテーブルを検索して最初にヒットしたレコードと関連づけられたオブジェクトを返します。フィールド名と検索語句を省略すると新規レコードを作成して、そのオブジェクトを返します。
+
+・レコードの読み書き
+ プロパティに対するリード/ライトの形でレコードの読み書きを行います。
+
+$record->フィールド名 = "foobar";	//書き込み
+echo $record->フィールド名;			// 読み出し
+
+・一括読みだし
+$arr = $record->fetch_array("フィールド名", "検索語句"[,options] );
+
+ 検索語句がヒットしたレコードを配列に読み出します。
+
+・レコードの削除
+$record->delete();
+
+・静的メソッド
+$arr = createRecords( PROGRAM_TBL|CATEGORY_TBL|CHANNEL_TBL|KEYWORD_TBL|RESERVE_TBL
+					 [,options] );
+ テーブルの全レコードをDBRecordオブジェクト配列として返します(低速)。optionsにSELECT文のWHERE節を追加して絞り込むことが出来ます。optionsは"WHERE ..."と記述してください。
+
+■ファイル群
+
+DBRecord.class.php
+ DBRecordクラス
+
+Keyword.class.php
+ キーワードレコードクラス(親:DBRecord)
+
+Reservation.class.php
+ 予約クラス。静的メソッドsimple()、静的メソッドcustom()。
+
+Settings.class.php
+ 設定の読み出し/保存を行うクラス(親:SimpleXML)
+
+cancelReservation.php
+ JavaScriptから呼ばれる予約取り消し
+
+changeReservation.php
+ JavaScriptから呼ばれる予約内容の更新
+
+channelInfo.php
+ チャンネル情報を返す(JavaScriptから呼ばれる)
+
+channelSetSID.php
+ チャンネルに対応するSIDを更新する(JavaScriptから呼ばれる)
+
+config.php.sample
+ config.phpのサンプルファイル
+
+customReservation.php
+ 詳細予約実行(JavaScriptから呼ばれる)
+
+deleteKeyword.php
+ キーワードの削除実行(keywordTable.phpから呼ばれる)
+
+envSetting.php
+ 環境設定
+
+getepg.php
+ EPG取得スクリプト
+
+index.php
+ トップページ(番組表)
+
+keywordTable.php
+ キーワードの管理ページ
+
+mediatomb.php
+ mediatombのDB更新スクリプト
+
+postsettings.php
+ 設定の更新(設定ページから呼ばれる)
+
+programTable.php
+ 番組検索ページ
+
+reclib.php
+ 雑多ライブラリ
+
+recomplete.php
+ 録画終了フラグを立てるスクリプト
+
+recordedTable.php
+ 録画済み一覧ページ
+
+reservationTable.php
+ 予約一覧ページ
+
+reservationform.php
+ 詳細予約のフォームを返す(JavaScriptから呼ばれる)
+
+sendstream.php
+ 録画中に視聴するためのストリーミングを流すスクリプト(未完成)
+
+simpleReservation.php
+ 簡易予約実行(JavaScriptから呼ばれる)
+
+systemSetting.php
+ システム設定ページ
+
+upgrade_to_201002.php
+ 2010年2月版へのアップデートスクリプト
+
+viewer.php
+ ASFヘッダを送るスクリプト
+
+templates/envSetting.html
+ 環境設定ページSmartyテンプレート
+
+templates/index.html
+ トップページSmartyテンプレート
+
+templates/keywordTable.html
+ キーワード一覧ページSmartyテンプレート
+
+templates/programTable.html
+ 番組検索ページSmartyテンプレート
+
+templates/recordedTable.html
+ 録画済み一覧ページSmartyテンプレート
+
+templates/reservationTable.html
+ 予約一覧ページページSmartyテンプレート
+
+templates/reservationform.html
+ 詳細予約フォームのSmartyテンプレート
+
+templates/systemSetting.html
+ システム設定ページSmartyテンプレート
+
+install/grscan.php
+ インストール:地上デジタルチャンネルスキャン(grscanが存在するときのみ)
+
+install/step1.php
+ インストール:ステップ1
+
+install/step2.php
+ インストール:ステップ2
+
+install/step3.php
+ インストール:ステップ3
+
+install/step4.php
+ インストール:ステップ4
+
+install/step5.php
+ インストール:ステップ5
+
+
--- a/Reservation.class.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/Reservation.class.php	Mon Mar 01 20:51:36 2010 +0900
@@ -235,7 +235,7 @@
 //				$filename = mb_convert_encoding( $filename, FILESYSTEM_ENCODING, "UTF-8" );
 				$filename = mb_convert_encoding( $filename, FILESYSTEM_ENCODING, "auto" );
 			}
-			$filename .= $RECORD_MODE[$mode]['suffix'];
+			$filename .= $RECORD_MODE["$mode"]['suffix'];
 			$thumbname = $filename.".jpg";
 
 			// サムネール
@@ -277,6 +277,7 @@
 			              "THUMB"    => INSTALL_PATH.$settings->thumbs."/".$thumbname,
 			              "FORMER"   => "".$settings->former_time,
 			              "FFMPEG"   => "".$settings->ffmpeg,
+			              "SID"      => $crec->sid,
 			);
 
 			// ATで予約する
--- a/Settings.class.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/Settings.class.php	Mon Mar 01 20:51:36 2010 +0900
@@ -18,7 +18,11 @@
 				$obj->autorec_mode = 0;
 				$obj->save();
 			}
-
+			// CSの録画
+			if( $obj->exists("cs_rec_flg") == 0 ) {
+				$obj->cs_rec_flg = 0;
+				$obj->save();
+			}
 			return $obj;
 		}
 		else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/channelInfo.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,36 @@
+<?php
+include_once('config.php');
+include_once( INSTALL_PATH . "/DBRecord.class.php" );
+include_once( INSTALL_PATH . "/Settings.class.php" );
+
+if( isset($_GET['channel_disc']) ) {
+	
+	try {
+		$crec = new DBRecord( CHANNEL_TBL, "channel_disc", $_GET['channel_disc'] );
+		
+		echo '<div class="prg_title">';
+		echo $crec->name . "</div>";
+		
+		// 種別
+		echo '<div class="prg_channel"><span class="labelLeft">種別:</span><span class="bold">';
+		echo $crec->type;
+		echo '</span></div>';
+		
+		// チャンネル
+		echo '<div class="prg_channel"><span class="labelLeft">物理チャンネル:</span><span class="bold">';
+		echo $crec->channel;
+		echo '</span></div>';
+		
+		// フォーム
+		echo '<form method="post" action="channelSetSID.php">';
+		echo '<div class="prg_channel"><span class="labelLeft">サービスID:</span>';
+		echo '<span><input type="text" name="n_sid" size="20" id="id_sid" value="'. $crec->sid .'" /></span>';
+		echo '<input type="hidden" name="n_channel_disc" id="id_disc" value="'. $crec->channel_disc .'" />';
+		echo '</div>';
+		echo '</form>';
+	}
+	catch( Exception $e ) {
+		echo "error:チャンネル情報の取得に失敗";
+	}
+}
+?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/channelSetSID.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,17 @@
+<?php
+include_once('config.php');
+include_once( INSTALL_PATH . "/DBRecord.class.php" );
+include_once( INSTALL_PATH . "/Settings.class.php" );
+
+
+if( isset($_POST['sid']) && isset($_POST['channel_disc']) ) {
+	
+	try {
+		$crec = new DBRecord( CHANNEL_TBL, "channel_disc", $_POST['channel_disc'] );
+		$crec->sid = trim($_POST['sid']);
+	}
+	catch( Exception $e ) {
+		// 無視
+	}
+}
+?>
\ No newline at end of file
--- a/config.php.sample	Sun Feb 14 17:01:02 2010 +0900
+++ b/config.php.sample	Mon Mar 01 20:51:36 2010 +0900
@@ -1,5 +1,8 @@
 <?php
 
+// settings/gr_channel.phpが作成された場合、
+// config.php内の$GR_CHANNEL_MAPは無視されます
+
 // 首都圏用地上デジタルチャンネルマップ
 // 識別子 => チャンネル番号
 $GR_CHANNEL_MAP = array(
@@ -40,13 +43,12 @@
 		'suffix' => '.ts',	// ファイル名のサフィックス
 	),
 	
-	/* Examples is as follows.
-	
 	1 => array(
-		'name' => 'Min PID',
-		'suffix' => '_tss.ts',
+		'name' => 'Minimum TS',	// 最小のTS
+		'suffix' => '_tss.ts',	// do-record.shのカスタマイズが必要
 	),
 	
+	/* Example is as follows.
 	2 => array(
 		'name' => '12Mbps MPEG4',
 		'suffix' => '.avi',
@@ -54,10 +56,18 @@
 	*/
 );
 
-// USE_KUROBON以外の定数は設定不要になりました
+
+// BSチューナーとして黒Friioを用いているのなら下のfalseをtrueに変えてください。
+
+define( "USE_KUROBON", false );
+
+
+
+//////////////////////////////////////////////////////////////////////////////
+// 以降の変数・定数はほとんどの場合、変更する必要はありません
+
 
 define( "INSTALL_PATH", dirname(__FILE__) );		// インストールパス
-define( "USE_KUROBON", false );						// BSチューナーとしてFriio BS/CSを使うならtrue
 
 // 以降は必要に応じて変更する
 
@@ -66,6 +76,24 @@
 define( "COMPLETE_CMD", INSTALL_PATH . "/recomplete.php" );	// 録画終了コマンド
 define( "GEN_THUMBNAIL", INSTALL_PATH . "/gen-thumbnail.sh" );	// サムネール生成スクリプト
 
+// BS/CSでEPGを取得するチャンネル
+// 通常は変える必要はありません
+// BSでepgdumpが頻繁に落ちる場合は、受信状態のいいチャンネルに変えることで
+// 改善するかもしれません
+
+define( "BS_EPG_CHANNEL",  "211"  );	// BS
+define( "CS1_EPG_CHANNEL", "CS8"  );	// CS1
+define( "CS2_EPG_CHANNEL", "CS24" );	// CS2
+
+
+// 地上デジタルチャンネルテーブルsettings/gr_channel.phpが存在するならそれを
+// 優先する
+if( file_exists( INSTALL_PATH."/settings/gr_channel.php" ) ) {
+	unset($GR_CHANNEL_MAP);
+	include_once( INSTALL_PATH."/settings/gr_channel.php" );
+}
+
+
 // 全国用BSデジタルチャンネルマップ
 $BS_CHANNEL_MAP = array(
         "3001.ontvjapan.com" => "101",
@@ -198,64 +226,73 @@
 // 予約テーブル
 define( "RESERVE_STRUCT", 
 	"id integer not null auto_increment primary key,".		// ID
-	"channel_disc varchar(128) default 'none',".			// channel disc
-	"channel_id integer default '0',".						// channel ID
-	"program_id integer default '0',".						// Program ID
-	"type varchar(8) default 'GR',".						// 種別(GR/BS/CS)
-	"channel varchar(10) default '0',".						// チャンネル
-	"title varchar(512) default 'none',".					// タイトル
-	"description text default null,".						// 説明
-	"category_id integer default '0',".						// カテゴリID
-	"starttime datetime default '1970-01-01 00:00:00',".	// 開始時刻
-	"endtime datetime default '1970-01-01 00:00:00',".		// 終了時刻
-	"job integer default '0',".								// job番号
+	"channel_disc varchar(128) not null default 'none',".	// channel disc
+	"channel_id integer not null  default '0',".			// channel ID
+	"program_id integer not null default '0',".				// Program ID
+	"type varchar(8) not null default 'GR',".				// 種別(GR/BS/CS)
+	"channel varchar(10) not null default '0',".			// チャンネル
+	"title varchar(512) not null default 'none',".			// タイトル
+	"description varchar(512) not null default 'none',".	// 説明 text->varchar
+	"category_id integer not null default '0',".			// カテゴリID
+	"starttime datetime not null default '1970-01-01 00:00:00',".	// 開始時刻
+	"endtime datetime not null default '1970-01-01 00:00:00',".		// 終了時刻
+	"job integer not null default '0',".					// job番号
 	"path blob default null,".								// 録画ファイルパス
-	"complete boolean default '0',".						// 完了フラグ
-	"reserve_disc varchar(128) default 'none',".			// 識別用hash
-	"autorec integer default '0',".							// キーワードID
-	"mode integer default '0'"								//録画モード
+	"complete boolean not null default '0',".				// 完了フラグ
+	"reserve_disc varchar(128) not null default 'none',".	// 識別用hash
+	"autorec integer not null default '0',".				// キーワードID
+	"mode integer not null default '0',".						//録画モード
+	"index reserve_ch_idx (channel_disc),".			// インデックス
+	"index reserve_st_idx (starttime)".
+	""
 );
 
 
 // 番組表テーブル
 define( "PROGRAM_STRUCT",
 	"id integer not null auto_increment primary key,".		// ID
-	"channel_disc varchar(128) default 'none',".			// channel disc
-	"channel_id integer default '0',".						// channel ID
-	"type varchar(8) default 'GR',".						// 種別(GR/BS/CS)
-	"channel varchar(10) default '0',".						// チャンネル
-	"title varchar(512) default 'none',".					// タイトル
-	"description text default null,".						// 説明
-	"category_id integer default '0',".						// カテゴリID
-	"starttime datetime default '1970-01-01 00:00:00',".	// 開始時刻
-	"endtime datetime default '1970-01-01 00:00:00',".		// 終了時刻
-	"program_disc char(128) default 'none',".	 			// 識別用hash
-	"autorec boolean default '1'"							// 自動録画有効無効
+	"channel_disc varchar(128) not null default 'none',".	// channel disc
+	"channel_id integer not null default '0',".				// channel ID
+	"type varchar(8) not null default 'GR',".				// 種別(GR/BS/CS)
+	"channel varchar(10) not null default '0',".			// チャンネル
+	"title varchar(512) not null default 'none',".			// タイトル
+	"description varchar(512) not null default 'none',".	// 説明 text->varchar
+	"category_id integer not null default '0',".			// カテゴリID
+	"starttime datetime not null default '1970-01-01 00:00:00',".	// 開始時刻
+	"endtime datetime not null default '1970-01-01 00:00:00',".		// 終了時刻
+	"program_disc varchar(128) not null default 'none',".	 		// 識別用hash
+	"autorec boolean not null default '1',".					// 自動録画有効無効
+	"index program_ch_idx (channel_disc),".			// インデックス
+	"index program_st_idx (starttime)".
+	""
 );
 
 
 define( "CHANNEL_STRUCT",
 	"id integer not null auto_increment primary key,".		// ID
-	"type varchar(8) default 'GR',".						// 種別
-	"channel varchar(10) default '0',".						// channel
-	"name varchar(512) default 'none',".					// 表示名
-	"channel_disc varchar(128) default 'none'"				// 識別用hash
+	"type varchar(8) not null default 'GR',".				// 種別
+	"channel varchar(10) not null default '0',".			// channel
+	"name varchar(512) not null default 'none',".			// 表示名
+	"channel_disc varchar(128) not null default 'none',".	// 識別用hash
+	"sid varchar(64) not null default 'hd'"					// サービスID用02/23/2010追加
 );
 
 define( "CATEGORY_STRUCT",
 	"id integer not null auto_increment primary key,".		// ID
-	"name_jp varchar(512) default 'none',".					// 表示名
-	"name_en varchar(512) default 'none',".					// 同上
-	"category_disc varchar(128) default 'none'"				// 識別用hash
+	"name_jp varchar(512) not null default 'none',".		// 表示名
+	"name_en varchar(512) not null default 'none',".		// 同上
+	"category_disc varchar(128) not null default 'none'"	// 識別用hash
 );
 
 
 define( "KEYWORD_STRUCT",
 	"id integer not null auto_increment primary key,".		// ID
-	"keyword varchar(512) default '*',".					// 表示名
-	"type varchar(8) default '*',".							// 種別
-	"channel_id integer default '0',".						// channel ID
-	"category_id integer default '0',".						// カテゴリID
-	"use_regexp boolean default '0'"						// 正規表現を使用するなら1
+	"keyword varchar(512) not null default '*',".			// 表示名
+	"type varchar(8) not null default '*',".				// 種別
+	"channel_id integer not null default '0',".				// channel ID
+	"category_id integer not null default '0',".			// カテゴリID
+	"use_regexp boolean not null default '0',".				// 正規表現を使用するなら1
+	"autorec_mode integer not null default '0',".						// 自動録画のモード02/23/2010追加
+	"weekofday enum ('0','1','2','3','4','5','6','7' ) default '7'"		// 曜日、同追加
 );
 ?>
--- a/do-record.sh.pt1	Sun Feb 14 17:01:02 2010 +0900
+++ b/do-record.sh.pt1	Mon Mar 01 20:51:36 2010 +0900
@@ -7,7 +7,6 @@
 echo "MODE : $MODE"
 
 RECORDER=/usr/local/bin/recpt1
-B25=/usr/local/bin/b25_bcas
 
 case $CHANNEL in
     101|102|191|192|193) SID=$CHANNEL ;;
--- a/do-record.sh.test	Sun Feb 14 17:01:02 2010 +0900
+++ b/do-record.sh.test	Mon Mar 01 20:51:36 2010 +0900
@@ -5,9 +5,10 @@
 echo "TUNER : $TUNER"
 echo "TYPE : $TYPE"
 echo "MODE : $MODE"
+echo "SID  : $SID"
 
 RECORDER=/usr/local/bin/recpt1
 B25=/usr/local/bin/b25_bcas
 
 /bin/date >${OUTPUT}
-#$RECORDER $CHANNEL $DURATION ${OUTPUT} --b25 --strip >/dev/null
+printenv >>${OUTPUT}
--- a/epgrec_upgrade.php	Sun Feb 14 17:01:02 2010 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#!/usr/bin/php
-<?php
-include_once('config.php');
-include_once(INSTALL_PATH . '/Settings.class.php' );
-
-$settings = Settings::factory();
-
- $dbh = mysql_connect( $settings->db_host, $settings->db_user, $settings->db_pass );
- if( $dbh !== false ) {
-	
-	$sqlstr = "use ".$settings->db_name;
-	mysql_query( $sqlstr );
-	
-	$sqlstr = "set NAMES 'utf8'";
-	mysql_query( $sqlstr );
-	
-	// RESERVE_TBL
-	// description -> text
-	$sqlstr = "alter table ".RESERVE_TBL." modify description text default null;";
-	mysql_query( $sqlstr );
-	// path -> blob
-	$sqlstr = "alter table ".RESERVE_TBL." modify path blob default null;";
-	mysql_query( $sqlstr );
-	
-	// PROGRAM_TBL
-	// descripton -> text
-	$sqlstr = "alter table ".PROGRAM_TBL." modify description text default null;";
-	mysql_query( $sqlstr );
- }
- else exit( "Can't connect DB\n");
-
-?>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getepg.old.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,218 @@
+#!/usr/bin/php
+<?php
+  include_once('config.php');
+  include_once( INSTALL_PATH . '/DBRecord.class.php' );
+  include_once( INSTALL_PATH . '/Reservation.class.php' );
+  include_once( INSTALL_PATH . '/Keyword.class.php' );
+  include_once( INSTALL_PATH . '/Settings.class.php' );
+  
+  $settings = Settings::factory();
+  
+  if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
+  if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+
+  // BSを処理する
+  if( $settings->bs_tuners != 0 ) {
+	// 録画重複チェック
+	$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
+	if( $num == 0 ) {
+	 	$cmdline = "CHANNEL=211 DURATION=180 TYPE=BS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+  		exec( $cmdline );
+  		$cmdline = $settings->epgdump." /BS ".$settings->temp_data." ".$settings->temp_xml;
+  		exec( $cmdline );
+  		storeProgram( "BS", $settings->temp_xml );
+  		if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
+  		if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+	}
+
+	// CS
+	if ($settings->cs_rec_flg != 0) {
+		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
+		if( $num == 0 ) {
+			$cmdline = "CHANNEL=CS8 DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+			exec( $cmdline );
+			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$settings->temp_xml;
+			exec( $cmdline );
+			storeProgram( "CS", $settings->temp_xml );
+			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
+			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+		}
+		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
+		if( $num == 0 ) {
+			$cmdline = "CHANNEL=CS24 DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+			exec( $cmdline );
+			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$settings->temp_xml;
+			exec( $cmdline );
+			storeProgram( "CS", $settings->temp_xml );
+			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
+			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+	  	}
+  	}
+  }
+  
+  // 地上波を処理する
+  if( $settings->gr_tuners != 0 ) {
+	foreach( $GR_CHANNEL_MAP as $key=>$value ){
+		// 録画重複チェック
+		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND type = 'GR' AND endtime > now() AND starttime < addtime( now(), '00:01:10')" );
+		if( $num == 0 ) {
+			$cmdline = "CHANNEL=".$value." DURATION=60 TYPE=GR TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+			exec( $cmdline );
+			$cmdline = $settings->epgdump." ".$key." ".$settings->temp_data." ".$settings->temp_xml;
+			exec( $cmdline );
+			storeProgram( "GR", $settings->temp_xml );
+ 			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
+  			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+  		}
+  	}
+  }
+  
+  // 不要なプログラムの削除
+  // 8日以上前のプログラムを消す
+  $arr = array();
+  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE endtime < subdate( now(), 8 )" );
+  foreach( $arr as $val ) $val->delete();
+	
+  // 8日以上先のデータがあれば消す
+  $arr = array();
+  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE starttime  > adddate( now(), 8 )" );
+  foreach( $arr as $val ) $val->delete();
+  
+  // キーワード自動録画予約
+  $arr = array();
+  $arr = Keyword::createKeywords();
+  foreach( $arr as $val ) {
+	try {
+		$val->reservation();
+	}
+	catch( Exception $e ) {
+		// 無視
+	}
+  }
+  
+  exit();
+  
+  function storeProgram( $type, $xmlfile ) {
+	global $BS_CHANNEL_MAP, $GR_CHANNEL_MAP, $CS_CHANNEL_MAP;
+	// チャンネルマップファイルの準備
+	$map = array();
+	if( $type == "BS" ) $map = $BS_CHANNEL_MAP;
+	else if( $type == "GR") $map = $GR_CHANNEL_MAP;
+	else if( $type == "CS") $map = $CS_CHANNEL_MAP;
+	
+	// XML parse
+  	$xml = @simplexml_load_file( $xmlfile );
+	if( $xml === false ) {
+		return;	// XMLが読み取れないなら何もしない
+	}
+	// channel抽出
+	foreach( $xml->channel as $ch ) {
+		$disc = $ch['id'];
+	 try {
+		// チャンネルデータを探す
+		$num = DBRecord::countRecords( CHANNEL_TBL , "WHERE channel_disc = '" . $disc ."'" );
+		if( $num == 0 ) {
+			// チャンネルデータがないなら新規作成
+			$rec = new DBRecord( CHANNEL_TBL );
+			$rec->type = $type;
+			$rec->channel = $map["$disc"];
+			$rec->channel_disc = $disc;
+			$rec->name = $ch->{'display-name'};
+		}
+		else {
+			// 存在した場合も、とりあえずチャンネル名は更新する
+			$rec = new DBRecord(CHANNEL_TBL, "channel_disc", $disc );
+			$rec->name = $ch->{'display-name'};
+		}
+	 }
+	 catch( Exception $e ) {
+		// 無視
+	 }
+	}
+	// channel 終了
+	
+	// programme 取得
+	
+	foreach( $xml->programme as $program ) {
+		$channel_disc = $program['channel']; 
+		$channel = $map["$channel_disc"];
+		$starttime = str_replace(" +0900", '', $program['start'] );
+		$endtime = str_replace( " +0900", '', $program['stop'] );
+		$title = $program->title;
+		$desc = $program->desc;
+		$cat_ja = "";
+		$cat_en = "";
+		foreach( $program->category as $cat ) {
+			if( $cat['lang'] == "ja_JP" ) $cat_ja = $cat;
+			if( $cat['lang'] == "en" ) $cat_en = $cat;
+		}
+		$program_disc = md5( $channel_disc . $starttime . $endtime );
+		// printf( "%s %s %s %s %s %s %s \n", $program_disc, $channel, $starttime, $endtime, $title, $desc, $cat_ja );
+		try {
+		 // カテゴリを処理する
+		 $category_disc = md5( $cat_ja . $cat_en );
+		 $num = DBRecord::countRecords(CATEGORY_TBL, "WHERE category_disc = '".$category_disc."'" );
+		 $cat_rec = null;
+		 if( $num == 0 ) {
+			// 新規カテゴリの追加
+			$cat_rec = new DBRecord( CATEGORY_TBL );
+			$cat_rec->name_jp = $cat_ja;
+			$cat_rec->name_en = $cat_en;
+		 	$cat_rec->category_disc = $category_disc;
+		 }
+		 else
+			$cat_rec = new DBRecord(CATEGORY_TBL, "category_disc" , $category_disc );
+		  //
+		 $channel_rec = new DBRecord(CHANNEL_TBL, "channel_disc", $channel_disc );
+		 $num = DBRecord::countRecords(PROGRAM_TBL, "WHERE program_disc = '".$program_disc."'" );
+		 if( $num == 0 ) {
+			// 新規番組
+			// 重複チェック 同時間帯にある番組
+			$options = "WHERE channel_disc = '".$channel_disc."' ".
+				"AND starttime < '". $endtime ."' AND endtime > '".$starttime."'";
+			$battings = DBRecord::countRecords(PROGRAM_TBL, $options );
+			if( $battings > 0 ) {
+				// 重複発生=おそらく放映時間の変更
+				$records = DBRecord::createRecords(PROGRAM_TBL, $options );
+				foreach( $records as $rec ) {
+					// 自動録画予約された番組は放映時間変更と同時にいったん削除する
+					try {
+						$reserve = new DBRecord(RESERVE_TBL, "program_id", $rec->id );
+						if( $reserve->autorec ) {
+							Reservation::cancel( $reserve->id );
+						}
+					}
+					catch( Exception $e ) {
+						//無視
+					}
+					// 番組削除
+					$rec->delete();
+				}
+			}
+			// //
+			$rec = new DBRecord( PROGRAM_TBL );
+			$rec->channel_disc = $channel_disc;
+			$rec->channel_id = $channel_rec->id;
+			$rec->type = $type;
+			$rec->channel = $channel_rec->channel;
+			$rec->title = $title;
+			$rec->description = $desc;
+			$rec->category_id = $cat_rec->id;
+			$rec->starttime = $starttime;
+			$rec->endtime = $endtime;
+			$rec->program_disc = $program_disc;
+		 }
+		 else {
+			// 番組内容更新
+			$rec = new DBRecord( PROGRAM_TBL, "program_disc", $program_disc );
+			$rec->title = $title;
+		 	$rec->description = $desc;
+			$rec->category_id = $cat_rec->id;
+		 }
+		}
+		catch(Exception $e) {
+			exit( $e->getMessage() );
+		}
+	}
+  }
+?>
--- a/getepg.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/getepg.php	Mon Mar 01 20:51:36 2010 +0900
@@ -5,42 +5,71 @@
   include_once( INSTALL_PATH . '/Reservation.class.php' );
   include_once( INSTALL_PATH . '/Keyword.class.php' );
   include_once( INSTALL_PATH . '/Settings.class.php' );
-
+  
+  // 後方互換性
+  if( ! defined( "BS_EPG_CHANNEL" )  ) define( "BS_EPG_CHANNEL",  "211"  );
+  if( ! defined( "CS1_EPG_CHANNEL" ) ) define( "CS1_EPG_CHANNEL", "CS8"  );
+  if( ! defined( "CS2_EPG_CHANNEL" ) ) define( "CS2_EPG_CHANNEL", "CS24" );
+  
+  
+  function check_file( $file ) {
+	// ファイルがないなら無問題
+	if( ! file_exists( $file ) ) return true;
+	
+	// 1時間以上前のファイルなら削除してやり直す
+	if( (time() - filemtime( $file )) > 3600 ) {
+		@unlink( $file );
+		return true;
+	}
+	
+	return false;
+  }
+  
   $settings = Settings::factory();
-
+  
+  $temp_xml_bs  = $settings->temp_xml."_bs";
+  $temp_xml_cs1 = $settings->temp_xml."_cs1";
+  $temp_xml_cs2 = $settings->temp_xml."_cs2";
+  $temp_xml_gr  = $settings->temp_xml."_gr";
+  
   if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
-  if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
-
+  
   // BSを処理する
   if( $settings->bs_tuners != 0 ) {
 	// 録画重複チェック
 	$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
-	if( $num < $settings->bs_tuners ) {
-	 	$cmdline = "CHANNEL=211 DURATION=180 TYPE=BS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+	if( $num < $settings->bs_tuners ) { //xxx
+//	if( ($num == 0) && check_file($temp_xml_bs) ) { //orig
+	 	$cmdline = "CHANNEL=".BS_EPG_CHANNEL." DURATION=180 TYPE=BS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
   		exec( $cmdline );
-  		$cmdline = $settings->epgdump." /BS ".$settings->temp_data." ".$settings->temp_xml;
+  		$cmdline = $settings->epgdump." /BS ".$settings->temp_data." ".$temp_xml_bs;
   		exec( $cmdline );
-  		storeProgram( "BS", $settings->temp_xml );
+		$cmdline = INSTALL_PATH."/storeProgram.php BS ".$temp_xml_bs." >/dev/null 2>&1 &";
+		exec( $cmdline );
   		if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
-  		if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+	}
 
-		// CS
-		if ($settings->cs_rec_flg != 0) {
-			$cmdline = "CHANNEL=CS8 DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+	// CS
+	if ($settings->cs_rec_flg != 0) {
+		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
+		if( ($num == 0) && check_file($temp_xml_cs1) ) {
+			$cmdline = "CHANNEL=".CS1_EPG_CHANNEL." DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
 			exec( $cmdline );
-			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$settings->temp_xml;
+			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$temp_xml_cs1;
 			exec( $cmdline );
-			storeProgram( "CS", $settings->temp_xml );
+			$cmdline = INSTALL_PATH."/storeProgram.php CS ".$temp_xml_cs1." >/dev/null 2>&1 &";
+			exec( $cmdline );
 			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
-			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
-
-			$cmdline = "CHANNEL=CS24 DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
+		}
+		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND (type = 'BS' OR type = 'CS') AND endtime > now() AND starttime < addtime( now(), '00:03:05')" );
+		if( ($num == 0) && check_file($temp_xml_cs2) ) {
+			$cmdline = "CHANNEL=".CS2_EPG_CHANNEL." DURATION=120 TYPE=CS TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
 			exec( $cmdline );
-			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$settings->temp_xml;
+			$cmdline = $settings->epgdump." /CS ".$settings->temp_data." ".$temp_xml_cs2;
 			exec( $cmdline );
-			storeProgram( "CS", $settings->temp_xml );
+			$cmdline = INSTALL_PATH."/storeProgram.php CS ".$temp_xml_cs2." >/dev/null 2>&1 &";
+			exec( $cmdline );
 			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
-			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
 	  	}
   	}
   }
@@ -50,164 +79,17 @@
 	foreach( $GR_CHANNEL_MAP as $key=>$value ){
 		// 録画重複チェック
 		$num = DBRecord::countRecords(  RESERVE_TBL, "WHERE complete = '0' AND type = 'GR' AND endtime > now() AND starttime < addtime( now(), '00:01:10')" );
-		if( $num < $settings->gr_tuners ) {
+		if( $num < $settings->gr_tuners ) { //xxx
+//		if( ($num == 0) && check_file($temp_xml_gr.$value."") ) {
 			$cmdline = "CHANNEL=".$value." DURATION=60 TYPE=GR TUNER=0 MODE=0 OUTPUT=".$settings->temp_data." ".DO_RECORD . " >/dev/null 2>&1";
 			exec( $cmdline );
-			$cmdline = $settings->epgdump." ".$key." ".$settings->temp_data." ".$settings->temp_xml;
+			$cmdline = $settings->epgdump." ".$key." ".$settings->temp_data." ".$temp_xml_gr.$value."";
 			exec( $cmdline );
-			storeProgram( "GR", $settings->temp_xml );
- 			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
-  			if( file_exists( $settings->temp_xml ) ) @unlink( $settings->temp_xml );
+			$cmdline = INSTALL_PATH."/storeProgram.php GR ".$temp_xml_gr.$value." >/dev/null 2>&1 &";
+			exec( $cmdline );
+			if( file_exists( $settings->temp_data ) ) @unlink( $settings->temp_data );
   		}
   	}
   }
-
-  // 不要なプログラムの削除
-  // 8日以上前のプログラムを消す
-  $arr = array();
-  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE endtime < subdate( now(), 8 )" );
-  foreach( $arr as $val ) $val->delete();
-
-  // 8日以上先のデータがあれば消す
-  $arr = array();
-  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE starttime  > adddate( now(), 8 )" );
-  foreach( $arr as $val ) $val->delete();
-
-  // キーワード自動録画予約
-  $arr = array();
-  $arr = Keyword::createKeywords();
-  foreach( $arr as $val ) {
-	try {
-		$val->reservation();
-	}
-	catch( Exception $e ) {
-		// 無視
-	}
-  }
-
-  exit();
-
-  function storeProgram( $type, $xmlfile ) {
-	global $BS_CHANNEL_MAP, $GR_CHANNEL_MAP, $CS_CHANNEL_MAP;
-	// チャンネルマップファイルの準備
-	$map = array();
-	if( $type == "BS" ) $map = $BS_CHANNEL_MAP;
-	else if( $type == "GR") $map = $GR_CHANNEL_MAP;
-	else if( $type == "CS") $map = $CS_CHANNEL_MAP;
-
-	// XML parse
-  	$xml = @simplexml_load_file( $xmlfile );
-	if( $xml === false ) {
-		return;	// XMLが読み取れないなら何もしない
-	}
-	// channel抽出
-	foreach( $xml->channel as $ch ) {
-		$disc = $ch['id'];
-	 try {
-		// チャンネルデータを探す
-		$num = DBRecord::countRecords( CHANNEL_TBL , "WHERE channel_disc = '" . $disc ."'" );
-		if( $num == 0 ) {
-			// チャンネルデータがないなら新規作成
-			$rec = new DBRecord( CHANNEL_TBL );
-			$rec->type = $type;
-			$rec->channel = $map["$disc"];
-			$rec->channel_disc = $disc;
-			$rec->name = $ch->{'display-name'};
-		}
-		else {
-			// 存在した場合も、とりあえずチャンネル名は更新する
-			$rec = new DBRecord(CHANNEL_TBL, "channel_disc", $disc );
-			$rec->name = $ch->{'display-name'};
-		}
-	 }
-	 catch( Exception $e ) {
-		// 無視
-	 }
-	}
-	// channel 終了
-
-	// programme 取得
-
-	foreach( $xml->programme as $program ) {
-		$channel_disc = $program['channel'];
-		$channel = $map["$channel_disc"];
-		$starttime = str_replace(" +0900", '', $program['start'] );
-		$endtime = str_replace( " +0900", '', $program['stop'] );
-		$title = $program->title;
-		$desc = $program->desc;
-		$cat_ja = "";
-		$cat_en = "";
-		foreach( $program->category as $cat ) {
-			if( $cat['lang'] == "ja_JP" ) $cat_ja = $cat;
-			if( $cat['lang'] == "en" ) $cat_en = $cat;
-		}
-		$program_disc = md5( $channel_disc . $starttime . $endtime );
-		// printf( "%s %s %s %s %s %s %s \n", $program_disc, $channel, $starttime, $endtime, $title, $desc, $cat_ja );
-		try {
-		 // カテゴリを処理する
-		 $category_disc = md5( $cat_ja . $cat_en );
-		 $num = DBRecord::countRecords(CATEGORY_TBL, "WHERE category_disc = '".$category_disc."'" );
-		 $cat_rec = null;
-		 if( $num == 0 ) {
-			// 新規カテゴリの追加
-			$cat_rec = new DBRecord( CATEGORY_TBL );
-			$cat_rec->name_jp = $cat_ja;
-			$cat_rec->name_en = $cat_en;
-		 	$cat_rec->category_disc = $category_disc;
-		 }
-		 else
-			$cat_rec = new DBRecord(CATEGORY_TBL, "category_disc" , $category_disc );
-		  //
-		 $channel_rec = new DBRecord(CHANNEL_TBL, "channel_disc", $channel_disc );
-		 $num = DBRecord::countRecords(PROGRAM_TBL, "WHERE program_disc = '".$program_disc."'" );
-		 if( $num == 0 ) {
-			// 新規番組
-			// 重複チェック 同時間帯にある番組
-			$options = "WHERE channel_disc = '".$channel_disc."' ".
-				"AND starttime < '". $endtime ."' AND endtime > '".$starttime."'";
-			$battings = DBRecord::countRecords(PROGRAM_TBL, $options );
-			if( $battings > 0 ) {
-				// 重複発生=おそらく放映時間の変更
-				$records = DBRecord::createRecords(PROGRAM_TBL, $options );
-				foreach( $records as $rec ) {
-					// 自動録画予約された番組は放映時間変更と同時にいったん削除する
-					try {
-						$reserve = new DBRecord(RESERVE_TBL, "program_id", $rec->id );
-						if( $reserve->autorec ) {
-							Reservation::cancel( $reserve->id );
-						}
-					}
-					catch( Exception $e ) {
-						//無視
-					}
-					// 番組削除
-					$rec->delete();
-				}
-			}
-			// //
-			$rec = new DBRecord( PROGRAM_TBL );
-			$rec->channel_disc = $channel_disc;
-			$rec->channel_id = $channel_rec->id;
-			$rec->type = $type;
-			$rec->channel = $channel_rec->channel;
-			$rec->title = $title;
-			$rec->description = $desc;
-			$rec->category_id = $cat_rec->id;
-			$rec->starttime = $starttime;
-			$rec->endtime = $endtime;
-			$rec->program_disc = $program_disc;
-		 }
-		 else {
-			// 番組内容更新
-			$rec = new DBRecord( PROGRAM_TBL, "program_disc", $program_disc );
-			$rec->title = $title;
-		 	$rec->description = $desc;
-			$rec->category_id = $cat_rec->id;
-		 }
-		}
-		catch(Exception $e) {
-			exit( $e->getMessage() );
-		}
-	}
-  }
+  
 ?>
--- a/index.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/index.php	Mon Mar 01 20:51:36 2010 +0900
@@ -49,12 +49,19 @@
  else if( $type == "GR" ) $channel_map = $GR_CHANNEL_MAP;
  else if( $type == "CS" ) $channel_map = $CS_CHANNEL_MAP;
  $st = 0;
- $prec = new DBRecord(PROGRAM_TBL);
+ $prec = null;
+ try {
+ 	$prec = new DBRecord(PROGRAM_TBL);
+ }
+ catch( Exception $e ) {
+	exit('プログラムテーブルが存在しないようです。インストールをやり直してください.');
+ }
  foreach( $channel_map as $channel_disc => $channel ) {
 	$prev_end = $top_time;
  	try {
 		$crec = new DBRecord( CHANNEL_TBL, "channel_disc", $channel_disc );
 		$programs[$st]["station_name"]  = $crec->name;
+		$programs[$st]["channel_disc"]  = $crec->channel_disc;
 		
 		$reca = $prec->fetch_array( "channel_disc", $channel_disc,
 		                                  "endtime > '".toDatetime($top_time)."' ".
@@ -104,7 +111,8 @@
 		}
 	}
 	 catch( exception $e ) {
-		exit( $e->getMessage() );
+//		exit( $e->getMessage() );
+//		何もしない
  	}
  	// 空きを埋める
 	if( ($last_time - $prev_end) > 0 ) {
@@ -221,4 +229,4 @@
  
  
  $smarty->display("index.html");
-?>
\ No newline at end of file
+?>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/install/grscan.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,35 @@
+<?php
+  include_once( "../config.php" );
+
+  $catv = "";
+
+  if( isset($_POST['catv']) ) {
+	if( $_POST['catv'] == 1) {
+		$catv = "catv";
+	}
+  }
+  echo '<p>チャンネルスキャン実行中...</p>';
+  flush();
+  ob_flush();
+
+  system("/usr/local/bin/grscan ".$catv." >".INSTALL_PATH."/settings/gr_channel.php" );
+
+  if( ! file_exists( INSTALL_PATH."/settings/gr_channel.php") ) {
+	exit("地上デジタルのスキャンに失敗したようです。自身で".INSTALL_PATH."/settings/gr_channel.phpを作成し、http://localhost/epgrec/install/step2.phpからインストールを再開させてください");
+  }
+  include_once( INSTALL_PATH."/settings/gr_channel.php" );
+
+echo "<p><b>地上デジタルチャンネルの設定確認</b></p>";
+
+echo "<div>現在、config.phpでは以下のチャンネルの受信が設定されています。受信不可能なチャ
+ンネルが混ざっていると番組表が表示できません。</div>";
+
+echo "<ul>";
+foreach( $GR_CHANNEL_MAP as $key => $value ) {
+        echo "<li>物理チャンネル".$value."</li>";
+}
+echo "</ul>";
+
+echo '<p><a href="step2.php">以上を確認し次の設定に進む</a></p>';
+
+?>
--- a/install/step1.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/install/step1.php	Mon Mar 01 20:51:36 2010 +0900
@@ -47,6 +47,7 @@
 	DO_RECORD,
 	COMPLETE_CMD,
 	INSTALL_PATH."/getepg.php",
+	INSTALL_PATH."/storeProgram.php",
 	$gen_thumbnail,
 );
 
@@ -77,6 +78,8 @@
 }
 echo "</div>";
 
+if( !file_exists( "/usr/local/bin/grscan" ) ) {
+
 echo "<p><b>地上デジタルチャンネルの設定確認</b></p>";
 
 echo "<div>現在、config.phpでは以下のチャンネルの受信が設定されています。受信不可能なチャンネルが混ざっていると番組表が表示できません。</div>";
@@ -87,7 +90,18 @@
 }
 echo "</ul>";
 
-
 echo '<p><a href="step2.php">以上を確認し次の設定に進む</a></p>';
 
+}
+else {
+
+echo'<p><b>地上デジタルチャンネルの設定</b><p>';
+echo '
+<form method="post" action="grscan.php" >
+<div>地上デジタルチャンネルスキャンを開始します。スキャンにはおよそ10~20分程度はかかります。ケーブルテレビをお使いの方は下のチェックボックスをオンにしてください</div>
+  <div>ケーブルテレビを使用:<input type="checkbox" name="catv" value="1" /></div>
+
+  <input type="submit" value="スキャンを開始する" />
+</form>';
+}
 ?>
--- a/install/step3.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/install/step3.php	Mon Mar 01 20:51:36 2010 +0900
@@ -51,6 +51,7 @@
 $smarty->compile_dir = "../templates_c/";
 $smarty->cache_dir = "../cache/";
 
+$smarty->assign( "record_mode", $RECORD_MODE );
 $smarty->assign( "settings", $settings );
 $smarty->assign( "install_path", INSTALL_PATH );
 $smarty->assign( "post_to", "step4.php" );
--- a/keywordTable.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/keywordTable.php	Mon Mar 01 20:51:36 2010 +0900
@@ -7,8 +7,12 @@
 include_once( INSTALL_PATH . "/Keyword.class.php" );
 // include_once( INSTALL_PATH . "/Settings.class.php" );
 
+
+$weekofdays = array( "月", "火", "水", "木", "金", "土", "日", "なし" );
+
 // 新規キーワードがポストされた
 
+
 if( isset($_POST["add_keyword"]) ) {
 	if( $_POST["add_keyword"] == 1 ) {
 		try {
@@ -18,6 +22,8 @@
 			$rec->category_id = $_POST['k_category'];
 			$rec->channel_id = $_POST['k_station'];
 			$rec->use_regexp = $_POST['k_use_regexp'];
+			$rec->weekofday = $_POST['k_weekofday'];
+			$rec->autorec_mode = $_POST['autorec_mode'];
 			
 			// 録画予約実行
 			$rec->reservation();
@@ -52,6 +58,10 @@
 		
 		$arr['use_regexp'] = $rec->use_regexp;
 		
+		$arr['weekofday'] = $weekofdays["$rec->weekofday"];
+		
+		$arr['autorec_mode'] = $RECORD_MODE[(int)$rec->autorec_mode]['name'];
+		
 		array_push( $keywords, $arr );
 	}
 }
--- a/programTable.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/programTable.php	Mon Mar 01 20:51:36 2010 +0900
@@ -6,9 +6,24 @@
 
 $settings = Settings::factory();
 
-
 $options = " WHERE starttime > '".date("Y-m-d H:i:s", time() + 300 )."'";
 
+// 曜日
+$weekofdays = array(
+					array( "name" => "月", "id" => 0, "selected" => "" ),
+					array( "name" => "火", "id" => 1, "selected" => "" ),
+					array( "name" => "水", "id" => 2, "selected" => "" ),
+					array( "name" => "木", "id" => 3, "selected" => "" ),
+					array( "name" => "金", "id" => 4, "selected" => "" ),
+					array( "name" => "土", "id" => 5, "selected" => "" ),
+					array( "name" => "日", "id" => 6, "selected" => "" ),
+					array( "name" => "なし", "id" => 7, "selected" => "" ),
+);
+
+$autorec_modes = $RECORD_MODE;
+$autorec_modes[(int)($settings->autorec_mode)]['selected'] = "selected";
+
+$weekofday = 7;
 $search = "";
 $use_regexp = 0;
 $type = "*";
@@ -50,6 +65,12 @@
 			$options .= " AND channel_id = '".$_POST['station']."'";
 		}
 	}
+	if( isset($_POST['weekofday']) ) {
+		$weekofday = $_POST['weekofday'];
+		if( $weekofday != 7 ) {
+			$options .= " AND WEEKDAY(starttime) = '".$weekofday."'";
+		}
+	}
 }
 $options .= " ORDER BY starttime ASC LIMIT 300";
 $do_keyword = 0;
@@ -79,7 +100,7 @@
 	}
 	
 	$k_category_name = "";
-	$crecs = DBRecord::createRecords(CATEGORY_TBL );
+	$crecs = DBRecord::createRecords(CATEGORY_TBL);
 	$cats = array();
 	$cats[0]['id'] = 0;
 	$cats[0]['name'] = "すべて";
@@ -135,6 +156,7 @@
 		if( $station == $c->id ) $k_station_name = $c->name;
 		array_push( $stations, $arr );
 	}
+	$weekofdays["$weekofday"]["selected"] = "selected" ;
 
 	$smarty = new Smarty();
 	$smarty->assign("sitetitle","番組検索");
@@ -150,6 +172,11 @@
 	$smarty->assign( "stations", $stations );
 	$smarty->assign( "k_station", $station );
 	$smarty->assign( "k_station_name", $k_station_name );
+	$smarty->assign( "weekofday", $weekofday );
+	$smarty->assign( "k_weekofday", $weekofdays["$weekofday"]["name"] );
+	$smarty->assign( "weekofday", $weekofday );
+	$smarty->assign( "weekofdays", $weekofdays );
+	$smarty->assign( "autorec_modes", $autorec_modes );
 	$smarty->display("programTable.html");
 }
 catch( exception $e ) {
--- a/simpleReservation.php	Sun Feb 14 17:01:02 2010 +0900
+++ b/simpleReservation.php	Mon Mar 01 20:51:36 2010 +0900
@@ -8,9 +8,9 @@
 if( ! isset( $_GET['program_id'] ) ) exit("Error: 番組が指定されていません" );
 $program_id = $_GET['program_id'];
 
+$settings = Settings::factory();
+
 try {
-    	$settings = Settings::factory();
-
 	Reservation::simple( $program_id, 0, $settings->autorec_mode);
 }
 catch( Exception $e ) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/storeProgram.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,193 @@
+#!/usr/bin/php
+<?php
+
+  $type = $argv[1];	// BS CS GR
+  $file = $argv[2];	// XMLファイル
+  
+  
+  // SIGTERMシグナル
+  function handler( $signo = 0 ) {
+	global $file;
+	if( file_exists( $file ) ) {
+		@unlink( $file );
+	}
+	exit();
+  }
+  
+  // デーモン化
+  function daemon() {
+	if( pcntl_fork() != 0 )
+		exit();
+	posix_setsid();
+	if( pcntl_fork() != 0 )
+		exit;
+	pcntl_signal(SIGTERM, "handler");
+  }
+  
+  
+  // デーモン化
+  daemon();
+  // プライオリティ低に
+  pcntl_setpriority(20);
+  
+  include_once('config.php');
+  include_once( INSTALL_PATH . '/DBRecord.class.php' );
+  include_once( INSTALL_PATH . '/Reservation.class.php' );
+  include_once( INSTALL_PATH . '/Keyword.class.php' );
+  include_once( INSTALL_PATH . '/Settings.class.php' );
+  
+  $settings = Settings::factory();
+  
+  if( file_exists( $file ) ) {
+	storeProgram( $type, $file );
+	@unlink( $file );
+  }
+  
+  // 不要なプログラムの削除
+  // 8日以上前のプログラムを消す
+  $arr = array();
+  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE endtime < subdate( now(), 8 )" );
+  foreach( $arr as $val ) $val->delete();
+	
+  // 8日以上先のデータがあれば消す
+  $arr = array();
+  $arr = DBRecord::createRecords(  PROGRAM_TBL, "WHERE starttime  > adddate( now(), 8 )" );
+  foreach( $arr as $val ) $val->delete();
+  
+  // キーワード自動録画予約
+  $arr = array();
+  $arr = Keyword::createKeywords();
+  foreach( $arr as $val ) {
+	try {
+		$val->reservation();
+	}
+	catch( Exception $e ) {
+		// 無視
+	}
+  }
+  exit();
+  
+  function storeProgram( $type, $xmlfile ) {
+	global $BS_CHANNEL_MAP, $GR_CHANNEL_MAP, $CS_CHANNEL_MAP;
+	// チャンネルマップファイルの準備
+	$map = array();
+	if( $type == "BS" ) $map = $BS_CHANNEL_MAP;
+	else if( $type == "GR") $map = $GR_CHANNEL_MAP;
+	else if( $type == "CS") $map = $CS_CHANNEL_MAP;
+	
+	// XML parse
+  	$xml = @simplexml_load_file( $xmlfile );
+	if( $xml === false ) {
+		return;	// XMLが読み取れないなら何もしない
+	}
+	// channel抽出
+	foreach( $xml->channel as $ch ) {
+		$disc = $ch['id'];
+	 try {
+		// チャンネルデータを探す
+		$num = DBRecord::countRecords( CHANNEL_TBL , "WHERE channel_disc = '" . $disc ."'" );
+		if( $num == 0 ) {
+			// チャンネルデータがないなら新規作成
+			$rec = new DBRecord( CHANNEL_TBL );
+			$rec->type = $type;
+			$rec->channel = $map["$disc"];
+			$rec->channel_disc = $disc;
+			$rec->name = $ch->{'display-name'};
+		}
+		else {
+			// 存在した場合も、とりあえずチャンネル名は更新する
+			$rec = new DBRecord(CHANNEL_TBL, "channel_disc", $disc );
+			$rec->name = $ch->{'display-name'};
+		}
+	 }
+	 catch( Exception $e ) {
+		// 無視
+	 }
+	}
+	// channel 終了
+	
+	// programme 取得
+	
+	foreach( $xml->programme as $program ) {
+		$channel_disc = $program['channel']; 
+		$channel = $map["$channel_disc"];
+		$starttime = str_replace(" +0900", '', $program['start'] );
+		$endtime = str_replace( " +0900", '', $program['stop'] );
+		$title = $program->title;
+		$desc = $program->desc;
+		$cat_ja = "";
+		$cat_en = "";
+		foreach( $program->category as $cat ) {
+			if( $cat['lang'] == "ja_JP" ) $cat_ja = $cat;
+			if( $cat['lang'] == "en" ) $cat_en = $cat;
+		}
+		$program_disc = md5( $channel_disc . $starttime . $endtime );
+		// printf( "%s %s %s %s %s %s %s \n", $program_disc, $channel, $starttime, $endtime, $title, $desc, $cat_ja );
+		try {
+		 // カテゴリを処理する
+		 $category_disc = md5( $cat_ja . $cat_en );
+		 $num = DBRecord::countRecords(CATEGORY_TBL, "WHERE category_disc = '".$category_disc."'" );
+		 $cat_rec = null;
+		 if( $num == 0 ) {
+			// 新規カテゴリの追加
+			$cat_rec = new DBRecord( CATEGORY_TBL );
+			$cat_rec->name_jp = $cat_ja;
+			$cat_rec->name_en = $cat_en;
+		 	$cat_rec->category_disc = $category_disc;
+		 }
+		 else
+			$cat_rec = new DBRecord(CATEGORY_TBL, "category_disc" , $category_disc );
+		  //
+		 $channel_rec = new DBRecord(CHANNEL_TBL, "channel_disc", $channel_disc );
+		 $num = DBRecord::countRecords(PROGRAM_TBL, "WHERE program_disc = '".$program_disc."'" );
+		 if( $num == 0 ) {
+			// 新規番組
+			// 重複チェック 同時間帯にある番組
+			$options = "WHERE channel_disc = '".$channel_disc."' ".
+				"AND starttime < '". $endtime ."' AND endtime > '".$starttime."'";
+			$battings = DBRecord::countRecords(PROGRAM_TBL, $options );
+			if( $battings > 0 ) {
+				// 重複発生=おそらく放映時間の変更
+				$records = DBRecord::createRecords(PROGRAM_TBL, $options );
+				foreach( $records as $rec ) {
+					// 自動録画予約された番組は放映時間変更と同時にいったん削除する
+					try {
+						$reserve = new DBRecord(RESERVE_TBL, "program_id", $rec->id );
+						if( $reserve->autorec ) {
+							Reservation::cancel( $reserve->id );
+						}
+					}
+					catch( Exception $e ) {
+						//無視
+					}
+					// 番組削除
+					$rec->delete();
+				}
+			}
+			// //
+			$rec = new DBRecord( PROGRAM_TBL );
+			$rec->channel_disc = $channel_disc;
+			$rec->channel_id = $channel_rec->id;
+			$rec->type = $type;
+			$rec->channel = $channel_rec->channel;
+			$rec->title = $title;
+			$rec->description = $desc;
+			$rec->category_id = $cat_rec->id;
+			$rec->starttime = $starttime;
+			$rec->endtime = $endtime;
+			$rec->program_disc = $program_disc;
+		 }
+		 else {
+			// 番組内容更新
+			$rec = new DBRecord( PROGRAM_TBL, "program_disc", $program_disc );
+			$rec->title = $title;
+		 	$rec->description = $desc;
+			$rec->category_id = $cat_rec->id;
+		 }
+		}
+		catch(Exception $e) {
+			exit( $e->getMessage() );
+		}
+	}
+  }
+?>
\ No newline at end of file
--- a/templates/envSetting.html	Sun Feb 14 17:01:02 2010 +0900
+++ b/templates/envSetting.html	Mon Mar 01 20:51:36 2010 +0900
@@ -115,9 +115,9 @@
 </div>
 
 
-<h3>キーワード自動録画の録画モード</h3>
+<h3>優先する録画モード</h3>
 <div class="setting">
-<div class="caption">キーワード自動録画を行う番組の録画モードを設定します。config.phpの$RECORD_MODEに複数の録画モードを登録しているのであれば、この設定でキーワード自動録画の録画モードを変更できます。デフォルトはモード0です。
+<div class="caption">キーワード自動録画や簡易録画を行う番組の録画モードを設定します。config.phpの$RECORD_MODEに複数の録画モードを登録し、do-record.shをカスタマイズているのであれば、その録画モードを優先して利用できます。キーワード自動録画はキーワード登録時に録画モードを設定することもできます。デフォルトはモード0です。
 </div>
 <select name="autorec_mode" id="id_autorec_mode" >
 {foreach from=$record_mode item=mode name=recmode}
--- a/templates/index.html	Sun Feb 14 17:01:02 2010 +0900
+++ b/templates/index.html	Mon Mar 01 20:51:36 2010 +0900
@@ -79,6 +79,31 @@
 		);
 	}
 	var PRG = {
+		chdialog:function(disc){
+			$('#channelDialog').dialog('close');
+			$.get('channelInfo.php', { channel_disc: disc },function(data) {
+				if(data.match(/^error/i)){
+					alert(data);
+				}
+				else {
+					var str = data;
+					str += '<div style="margin:2em 0 1em 0;text-align:center;"><a href="javascript:PRG.chupdate()" class="ui-state-default ui-corner-all ui-dialog-buttonpane button">更新</a></div>';
+					$('#channelDialog').html(str);
+					$('#channelDialog').dialog('open', 'center');
+					
+				}
+			});
+
+		},
+		chupdate:function() {
+			var v_sid = $('#id_sid').val();
+			var v_channel_disc = $('#id_disc').val();
+			$.post('channelSetSID.php', { channel_disc: v_channel_disc,
+						      sid: v_sid }, function(data) {
+				
+				$('#channelDialog').dialog('close');
+			});
+		},
 		rec:function(id){
 			$.get(INISet.prgRecordURL, { program_id: id } ,function(data){
 				if(data.match(/^error/i)){
@@ -289,6 +314,11 @@
 		var DG = $('#floatBox4Dialog');
 		DG.dialog({title:'録画予約',width:600});
 		DG.dialog('close');
+
+		var DG2 = $('#channelDialog');
+		DG2.dialog({title:'チャンネル情報',width:600});
+		DG2.dialog('close');
+
 		nowBar.INI();
 		CTG.INI();
 		MDA.SCR.INI();	// 番組表の位置保存
@@ -403,6 +433,12 @@
 #floatBox4Dialog .prg_rec_cfg{background:#EEE;padding:1em 2em;margin:0.4em 0;}
 #floatBox4Dialog .labelLeft {width:8em;float:left;text-align:right;}
 #floatBox4Dialog .button {padding:0.4em 1em;}
+
+#channelDialog .prg_title{font-size:120%;font-weight:bold;padding:0.4em 0;text-align:center;}
+#channelDialog .prg_rec_cfg{background:#EEE;padding:1em 2em;margin:0.4em 0;}
+#channelDialog .labelLeft {width:8em;float:left;text-align:right;}
+#channelDialog .button {padding:0.4em 1em;}
+
 -->
 </style>
 
@@ -482,7 +518,7 @@
 <div style="position:absolute;bottom:0;">
   <div class="tvtimeDM" style="float:left;">&nbsp;</div>
   {foreach from=$programs item=program }
-  <div class="ch_title"><div>{$program.station_name}</div></div>
+  <div class="ch_title" ><div style="cursor: pointer" onClick="javascript:PRG.chdialog('{$program.channel_disc}')" >{$program.station_name}</div></div>
   {/foreach}
 </div>
 <br style="clear:left;" />
@@ -532,6 +568,7 @@
 
 
 <div id="floatBox4Dialog">jQuery UI Dialog</div>
+<div id="channelDialog">jQuery UI Dialog</div>
 
 {literal}
 <script type="text/javascript">
--- a/templates/keywordTable.html	Sun Feb 14 17:01:02 2010 +0900
+++ b/templates/keywordTable.html	Mon Mar 01 20:51:36 2010 +0900
@@ -86,6 +86,8 @@
   <th>種別</th>
   <th>局</th>
   <th>カテゴリ</th>
+  <th>曜日</th>
+  <th>録画モード</th>
   <th>削除</th>
  </tr>
 
@@ -97,6 +99,8 @@
   <td>{$keyword.type}</td>
   <td>{$keyword.channel}</td>
   <td>{$keyword.category}</td>
+  <td>{$keyword.weekofday}</td>
+  <td>{$keyword.autorec_mode}</td>
   <td><input type="button" value="削除" onClick="javascript:PRG.delkey('{$keyword.id}')" /></td>
  </tr>
 {/foreach}
--- a/templates/programTable.html	Sun Feb 14 17:01:02 2010 +0900
+++ b/templates/programTable.html	Mon Mar 01 20:51:36 2010 +0900
@@ -176,6 +176,11 @@
   {foreach from=$cats item=cat}
   <option value="{$cat.id}" {$cat.selected}>{$cat.name}</option>
   {/foreach}
+  </select>
+曜日<select name='weekofday'>
+  {foreach from=$weekofdays item=day}
+  <option value="{$day.id}" {$day.selected}>{$day.name}</option>
+  {/foreach}
 </select>
 <input type="submit" value="絞り込む" />
 </form>
@@ -223,6 +228,7 @@
   <b>種別:</b>{if $k_type == "*"}すべて{else}{$k_type}{/if}
   <b>局:</b>{if $k_station == 0}すべて{else}{$k_station_name}{/if}
   <b>カテゴリ:</b>{if $k_category == 0}すべて{else}{$k_category_name}{/if}
+  <b>曜日:</b>{if $weekofday == 7}なし{else}{$k_weekofday}{/if}曜
   <b>件数:</b>{$programs|@count}
   <input type="hidden" name="add_keyword" value="{$do_keyword}" />
   <input type="hidden" name="k_use_regexp" value="{$use_regexp}" />
@@ -230,7 +236,13 @@
   <input type="hidden" name="k_type" value="{$k_type}" />
   <input type="hidden" name="k_category" value="{$k_category}" />
   <input type="hidden" name="k_station" value="{$k_station}" />
-  <input type="submit" value="この絞り込みを自動録画キーワードに登録" />
+  <input type="hidden" name="k_weekofday" value={$weekofday} />
+  <b>録画モード:</b><select name="autorec_mode" >
+  {foreach from=$autorec_modes item=mode name=recmode }
+     <option value="{$smarty.foreach.recmode.index}" {$mode.selected} >{$mode.name}</option>
+  {/foreach}
+   </select>
+  <br><input type="submit" value="この絞り込みを自動録画キーワードに登録" />
   </form>
 </div>
 {/if}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upgrade_to_201002.php	Mon Mar 01 20:51:36 2010 +0900
@@ -0,0 +1,138 @@
+#!/usr/bin/php
+<?php
+include_once('config.php');
+include_once(INSTALL_PATH . '/Settings.class.php' );
+
+
+// mysqli::multi_queryは動作がいまいちなので使わない
+
+function multi_query( $sqlstrs, $dbh ) {
+	$error = false;
+	
+	foreach( $sqlstrs as $sqlstr ) {
+		$res = mysql_query( $sqlstr );
+		if( $res === FALSE ) {
+			echo "failed: ". $sqlstr . "\n";
+			$error = true;
+		}
+	}
+	return $error;
+}
+
+
+$settings = Settings::factory();
+$dbh = mysql_connect( $settings->db_host, $settings->db_user, $settings->db_pass );
+if( $dbh !== FALSE ) {
+
+	$sqlstr = "use ".$settings->db_name;
+	mysql_query( $sqlstr );
+
+	$sqlstr = "set NAMES 'utf8'";
+	mysql_query( $sqlstr );
+	
+	// RESERVE_TBL
+
+	$sqlstrs = array (
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  channel_disc varchar(128) not null default 'none';",	// channel disc
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  channel_id integer not null  default '0';",			// channel ID
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  program_id integer not null default '0';",				// Program ID
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  type varchar(8) not null default 'GR';",				// 種別(GR/BS/CS)
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  channel varchar(10) not null default '0';",			// チャンネル
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  title varchar(512) not null default 'none';",			// タイトル
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  description varchar(512) not null default 'none';",		// 説明 text->varchar
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  category_id integer not null default '0';",			// カテゴリID
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  starttime datetime not null default '1970-01-01 00:00:00';",	// 開始時刻
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  endtime datetime not null default '1970-01-01 00:00:00';",		// 終了時刻
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  job integer not null default '0';",					// job番号
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  path blob default null;",								// 録画ファイルパス
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  complete boolean not null default '0';",				// 完了フラグ
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  reserve_disc varchar(128) not null default 'none';",	// 識別用hash
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  autorec integer not null default '0';",				// キーワードID
+	 "alter table ".$settings->tbl_prefix.RESERVE_TBL." modify  mode integer not null default '0';",					//録画モード
+	);
+	
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "予約テーブルのアップデートに失敗\n";
+	}
+	
+	$sqlstrs = array(
+	 "create index reserve_ch_idx on ".$settings->tbl_prefix.RESERVE_TBL."  (channel_disc);",
+	 "create index reserve_st_idx on ".$settings->tbl_prefix.RESERVE_TBL."  (starttime);",
+	);
+	
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "予約テーブルにインデックスが作成できません\n";
+	}
+	
+	// PROGRAM_TBL
+	
+	$sqlstrs = array (
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify channel_disc varchar(128) not null default 'none';",	// channel disc
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify channel_id integer not null default '0';",				// channel ID
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify type varchar(8) not null default 'GR';",				// 種別(GR/BS/CS)
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify channel varchar(10) not null default '0';",			// チャンネル
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify title varchar(512) not null default 'none';",			// タイトル
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify description varchar(512) not null default 'none';",	// 説明 text->varchar
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify category_id integer not null default '0';",			// カテゴリID
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify starttime datetime not null default '1970-01-01 00:00:00';",	// 開始時刻
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify endtime datetime not null default '1970-01-01 00:00:00';",		// 終了時刻
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify program_disc varchar(128) not null default 'none';",	 		// 識別用hash
+		"alter table ".$settings->tbl_prefix.PROGRAM_TBL." modify autorec boolean not null default '1';",					// 自動録画有効無効
+	);
+	
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "番組テーブルのアップデートに失敗\n";
+	}
+	
+	$sqlstrs = array(
+	 "create index program_ch_idx on ".$settings->tbl_prefix.PROGRAM_TBL." (channel_disc);",		// インデックス
+	 "create index program_st_idx on ".$settings->tbl_prefix.PROGRAM_TBL." (starttime);",			// インデックス
+	);
+	
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "番組テーブルにインデックスが作成できません\n";
+	}
+	
+	// CHANNEL_TBL
+	
+	$sqlstrs = array(
+	"alter table ".$settings->tbl_prefix.CHANNEL_TBL." modify type varchar(8) not null default 'GR';",				// 種別
+	"alter table ".$settings->tbl_prefix.CHANNEL_TBL." modify channel varchar(10) not null default '0';",			// channel
+	"alter table ".$settings->tbl_prefix.CHANNEL_TBL." modify name varchar(512) not null default 'none';",			// 表示名
+	"alter table ".$settings->tbl_prefix.CHANNEL_TBL." modify channel_disc varchar(128) not null default 'none';",	// 識別用hash
+	"alter table ".$settings->tbl_prefix.CHANNEL_TBL." add sid varchar(64) not null default 'hd'",				// サービスID用02/23/2010追加
+	);
+	
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "チャンネルテーブルのアップデートに失敗\n";
+	}
+	
+	// CATEGORY_TBL
+	
+	$sqlstrs  = array(
+	"alter table ".$settings->tbl_prefix.CATEGORY_TBL." modify name_jp varchar(512) not null default 'none';",		// 表示名
+	"alter table ".$settings->tbl_prefix.CATEGORY_TBL." modify name_en varchar(512) not null default 'none';",		// 同上
+	"alter table ".$settings->tbl_prefix.CATEGORY_TBL." modify category_disc varchar(128) not null default 'none'",	// 識別用hash
+	);
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "カテゴリテーブルのアップデートに失敗\n";
+	}
+	
+	// KEYWORD_TBL
+	
+	$sqlstrs = array(
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." modify keyword varchar(512) not null default '*';",			// 表示名
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." modify type varchar(8) not null default '*';",				// 種別
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." modify channel_id integer not null default '0';",				// channel ID
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." modify category_id integer not null default '0';",			// カテゴリID
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." modify use_regexp boolean not null default '0';",				// 正規表現を使用するなら1
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." add autorec_mode integer not null default '0';",						// 自動録画のモード02/23/2010追加
+	 "alter table ".$settings->tbl_prefix.KEYWORD_TBL." add weekofday enum ('0','1','2','3','4','5','6','7' ) default '7'",		// 曜日、同追加
+	);
+	if( multi_query( $sqlstrs, $dbh ) ) {
+		echo "キーワードテーブルのアップデートに失敗\n";
+	}
+}
+else
+	exit( "DBの接続に失敗\n" );
+?>
\ No newline at end of file