Hatena::ブログ(Diary)

適当な何かの別館 このページをアンテナに追加 RSSフィード

2011-09-18

epgrec EPG更新(時間追従)不具合パッチ(完全版)

***注意***
これは、本家用のパッチです。


あっちで公開した場当たり版で述べていた完全対策を行うパッチ
先にepgrec EPG放送局変動対処パッチ改良版を適用してからパッチするように(patchは賢いので必要ないかもしれないが念のため)

epgdumpの変更も伴うのでまとめたアーカイブを以下からダウン
http://www1.axfc.net/uploader/Sc/so/275848.zip [key:epgrec]

パッチ適用後は、未実行予約をepgrecのUIから全削除を行うこと
出来れば Recorder_programTbl もdrop空にするように

なお同梱の epgdumpのパッチは、カテゴリー(ジャンル)出力バグを改修済みである。

以下追記(13-03-08)
[バグの内容]
既存予約にピッタリ重なる形で別番組が移動してくると既存予約がキャンセルされずに残る。
というもの
なお既存予約されていた目的の番組は、移動先で追加予約されます。

[運用上で何が起きるのか]
・チューナーが不足する場合に旧予約に重なる形で移動してきた別番組が予約対象でも予約が行われない。
 (旧予約で録画が行われるが下記条件にて上書きされる場合がある)
・録画ファイル名の唯一性が確保できない(日時の"分"までが含まれない)場合は、旧予約の録画ファイルが新予約で上書きされる。
 その際に新旧予約が隣接していると糊代部分が重なるためその間は1つのファイルを2つのプロセスで書き込むことになる。
 (チュ−ナー不足による重複解消で旧予約の短縮が行われる場合はその限りではない)
・録画ファイル名の唯一性が確保できる場合は、2つの録画ファイルが残る。
・新予約の移動先でも条件が合えば不具合が連鎖する。
・・・といった感じで設定や設備・条件に左右されるため環境別で不具合が違うロクでもない状態になります。

[何処が悪いのか]
storeProgram.inc.phpの183行目

	$program_disc = md5( $channel_disc . $starttime . $endtime );

番組識別子を"チャンネル識別子+番組開始時間+番組終了時間"で生成している。
[バグの内容]で述べた番組編成変更が行われると別番組に同じ番組識別子が生成されるため番組識別子の唯一性が崩れてしまう。
EPG更新処理は、番組識別子の唯一性を前提に行われるため不具合が起きる。
といった次第です。

[修正内容]
epgrecの番組識別子生成に放送局内番組識別子(event_id)をくわえて唯一性を確保します。
放送局内番組識別子は、epgdumpをいじらないと出力されないので合わせてそれも行います。

2011-09-17 epgrec EPG放送局変動対処パッチ改良版

epgrec EPG放送局変動対処パッチ改良版

あっちで公表したパッチだが実際に局名変更があった場合にも対応できるよう改良した。

このパッチを当てることで
・番組表で放送局名と番組が別の局のものに変わってしまうことがある
・違う局の番組を録画されることがある
・予約したのに録画されないことがある
といった症状が改善される。

diff -u ./org/storeProgram.inc.php ./new/storeProgram.inc.php
--- ./org/storeProgram.inc.php	2011-09-18 02:16:56.833081000 +0900
+++ ./new/storeProgram.inc.php	2011-09-18 02:18:07.745810000 +0900
@@ -66,9 +66,18 @@
 			}
 		}
 		else {
-			// 存在した場合も、とりあえずチャンネル名は更新する
 			$rec = new DBRecord(CHANNEL_TBL, "channel_disc", $disc );
-			$rec->name = $ch->{'display-name'};
+			if( strcmp( $rec->name, $ch->{'display-name'} ) ){
+				$num = DBRecord::countRecords( CHANNEL_TBL , "WHERE name = '".$ch->{'display-name'}."'" );
+				if( $num == 0 )
+					$rec->name = $ch->{'display-name'};
+				else{
+					reclog( 'EPG更新::チャンネル名が違います('.$disc.' '.$rec->name.' -> '.$ch->{'display-name'}.' '.$xmlfile.')', E_ERROR );
+//					$new_name = $xmlfile.'.'.toDatetime(time());
+//					rename( $xmlfile, $new_name );
+					return;	//信頼できないデータなので終了
+				}
+			}
 		}
 	 }
 	 catch( Exception $e ) {