comparison Reservation.class.php @ 92:e2c37cc736db

merged with upstream
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 02 Mar 2010 23:20:06 +0900
parents f6b909678e51 36ac7c416bd7
children 49145003e6a3
comparison
equal deleted inserted replaced
91:f6b909678e51 92:e2c37cc736db
6 6
7 7
8 // 予約クラス 8 // 予約クラス
9 9
10 class Reservation { 10 class Reservation {
11 11
12 public static function simple( $program_id , $autorec = 0, $mode = 0) { 12 public static function simple( $program_id , $autorec = 0, $mode = 0) {
13 $settings = Settings::factory(); 13 $settings = Settings::factory();
14 $rval = 0; 14 $rval = 0;
15 try { 15 try {
16 $prec = new DBRecord( PROGRAM_TBL, "id", $program_id ); 16 $prec = new DBRecord( PROGRAM_TBL, "id", $program_id );
17 17
18 $rval = self::custom( 18 $rval = self::custom(
19 $prec->starttime, 19 $prec->starttime,
20 $prec->endtime, 20 $prec->endtime,
21 $prec->channel_id, 21 $prec->channel_id,
22 $prec->title, 22 $prec->title,
23 $prec->description, 23 $prec->description,
24 $prec->category_id, 24 $prec->category_id,
25 $program_id, 25 $program_id,
26 $autorec, 26 $autorec,
27 $mode ); 27 $mode );
28 28
29 } 29 }
30 catch( Exception $e ) { 30 catch( Exception $e ) {
31 throw $e; 31 throw $e;
32 } 32 }
33 return $rval; 33 return $rval;
34 } 34 }
35 35
36 public static function custom( 36 public static function custom(
37 $starttime, // 開始時間Datetime型 37 $starttime, // 開始時間Datetime型
38 $endtime, // 終了時間Datetime型 38 $endtime, // 終了時間Datetime型
39 $channel_id, // チャンネルID 39 $channel_id, // チャンネルID
40 $title = "none", // タイトル 40 $title = "none", // タイトル
48 $settings = Settings::factory(); 48 $settings = Settings::factory();
49 49
50 // 時間を計算 50 // 時間を計算
51 $start_time = toTimestamp( $starttime ); 51 $start_time = toTimestamp( $starttime );
52 $end_time = toTimestamp( $endtime ) + $settings->extra_time; 52 $end_time = toTimestamp( $endtime ) + $settings->extra_time;
53 53
54 if( $start_time < (time() + PADDING_TIME + 10) ) { // 現在時刻より3分先より小さい=すでに開始されている番組 54 if( $start_time < (time() + PADDING_TIME + 10) ) { // 現在時刻より3分先より小さい=すでに開始されている番組
55 $start_time = time() + PADDING_TIME + 10; // 録画開始時間を3分10秒先に設定する 55 $start_time = time() + PADDING_TIME + 10; // 録画開始時間を3分10秒先に設定する
56 } 56 }
57 $at_start = $start_time - PADDING_TIME; 57 $at_start = $start_time - PADDING_TIME;
58 $sleep_time = PADDING_TIME - $settings->former_time; 58 $sleep_time = PADDING_TIME - $settings->former_time;
59 $rec_start = $start_time - $settings->former_time; 59 $rec_start = $start_time - $settings->former_time;
60 60
61 // durationを計算しておく 61 // durationを計算しておく
62 $duration = $end_time - $rec_start; 62 $duration = $end_time - $rec_start;
63 if( $duration < ($settings->former_time + 60) ) { // 60秒以下の番組は弾く 63 if( $duration < ($settings->former_time + 60) ) { // 60秒以下の番組は弾く
64 throw new Exception( "終わりつつある/終わっている番組です" ); 64 throw new Exception( "終わりつつある/終わっている番組です" );
65 } 65 }
66 66
67 $rrec = null; 67 $rrec = null;
68 try { 68 try {
69 // 同一番組予約チェック 69 // 同一番組予約チェック
70 if( $program_id ) { 70 if( $program_id ) {
71 $num = DBRecord::countRecords( RESERVE_TBL, "WHERE program_id = '".$program_id."'" ); 71 $num = DBRecord::countRecords( RESERVE_TBL, "WHERE program_id = '".$program_id."'" );
72 if( $num ) { 72 if( $num ) {
73 throw new Exception("同一の番組が録画予約されています"); 73 throw new Exception("同一の番組が録画予約されています");
74 } 74 }
75 } 75 }
76 76
77 $crec = new DBRecord( CHANNEL_TBL, "id", $channel_id ); 77 $crec = new DBRecord( CHANNEL_TBL, "id", $channel_id );
78 78
79 // 既存予約数 = TUNER番号 79 // 既存予約数 = TUNER番号
80 $tuners = ($crec->type == "GR") ? $settings->gr_tuners : $settings->bs_tuners; 80 $tuners = ($crec->type == "GR") ? $settings->gr_tuners : $settings->bs_tuners;
81 $type_str = ($crec->type == "GR") ? "type = 'GR' " : "(type = 'BS' OR type = 'CS') "; 81 $type_str = ($crec->type == "GR") ? "type = 'GR' " : "(type = 'BS' OR type = 'CS') ";
82 82
83 $battings = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ". 83 $battings = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ".
84 "AND ".$type_str. 84 "AND ".$type_str.
85 "AND starttime < '".toDatetime($end_time) ."' ". 85 "AND starttime < '".toDatetime($end_time) ."' ".
86 "AND endtime > '".toDatetime($rec_start)."'" 86 "AND endtime > '".toDatetime($rec_start)."'"
87 ); 87 );
88 88
89 if( $battings >= $tuners ) { 89 if( $battings >= $tuners ) {
90 // 重複を発見した 90 // 重複を発見した
91 if( $settings->force_cont_rec == 1 ) { 91 if( $settings->force_cont_rec == 1 ) {
92 // 解消可能な重複かどうかを調べる 92 // 解消可能な重複かどうかを調べる
93 // 前後の予約数 93 // 前後の予約数
94 $nexts = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ". 94 $nexts = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ".
95 "AND ".$type_str. 95 "AND ".$type_str.
96 "AND starttime = '".toDatetime($end_time - $settings->former_time)."'"); 96 "AND starttime = '".toDatetime($end_time - $settings->former_time)."'");
97 97
98 $prevs = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ". 98 $prevs = DBRecord::countRecords( RESERVE_TBL, "WHERE complete = '0' ".
99 "AND ".$type_str. 99 "AND ".$type_str.
100 "AND endtime = '".$starttime."'" ); 100 "AND endtime = '".$starttime."'" );
101 101
102 // 前後を引いてもチューナー数と同数以上なら重複の解消は無理 102 // 前後を引いてもチューナー数と同数以上なら重複の解消は無理
103 if( ($battings - $nexts - $prevs) >= $tuners ) 103 if( ($battings - $nexts - $prevs) >= $tuners )
104 throw new Exception( "重複予約を解消できません" ); 104 throw new Exception( "重複予約を解消できません" );
105 105
106 // 直後の番組はあるか? 106 // 直後の番組はあるか?
107 if( $nexts ) { 107 if( $nexts ) {
108 // この番組の終わりをちょっとだけ早める 108 // この番組の終わりをちょっとだけ早める
109 $end_time = $end_time - $settings->former_time - $settings->rec_switch_time; 109 $end_time = $end_time - $settings->former_time - $settings->rec_switch_time;
110 $duration = $end_time - $rec_start; // durationを計算しなおす 110 $duration = $end_time - $rec_start; // durationを計算しなおす
111 } 111 }
112 $battings -= $nexts; 112 $battings -= $nexts;
113 113
114 // 直前の録画予約を見付ける 114 // 直前の録画予約を見付ける
115 $trecs = DBRecord::createRecords(RESERVE_TBL, "WHERE complete = '0' ". 115 $trecs = DBRecord::createRecords(RESERVE_TBL, "WHERE complete = '0' ".
116 "AND ".$type_str. 116 "AND ".$type_str.
117 "AND endtime = '".$starttime."'" ); 117 "AND endtime = '".$starttime."'" );
118 // 直前の番組をずらす 118 // 直前の番組をずらす
127 $prev_category_id = $trecs[$i]->category_id; 127 $prev_category_id = $trecs[$i]->category_id;
128 $prev_starttime = $trecs[$i]->starttime; 128 $prev_starttime = $trecs[$i]->starttime;
129 $prev_endtime = $trecs[$i]->endtime; 129 $prev_endtime = $trecs[$i]->endtime;
130 $prev_autorec = $trecs[$i]->autorec; 130 $prev_autorec = $trecs[$i]->autorec;
131 $prev_mode = $trecs[$i]->mode; 131 $prev_mode = $trecs[$i]->mode;
132 132
133 $prev_start_time = toTimestamp($prev_starttime); 133 $prev_start_time = toTimestamp($prev_starttime);
134 // 始まっていない予約? 134 // 始まっていない予約?
135 if( $prev_start_time > (time() + PADDING_TIME + $settings->former_time) ) { 135 if( $prev_start_time > (time() + PADDING_TIME + $settings->former_time) ) {
136 // 開始時刻を元に戻す 136 // 開始時刻を元に戻す
137 $prev_starttime = toDatetime( $prev_start_time + $settings->former_time ); 137 $prev_starttime = toDatetime( $prev_start_time + $settings->former_time );
138 // 終わりをちょっとだけずらす 138 // 終わりをちょっとだけずらす
139 $prev_endtime = toDatetime( toTimestamp($prev_endtime) - $settings->former_time - $settings->rec_switch_time ); 139 $prev_endtime = toDatetime( toTimestamp($prev_endtime) - $settings->former_time - $settings->rec_switch_time );
140 140
141 // tryのネスト 141 // tryのネスト
142 try { 142 try {
143 // いったん予約取り消し 143 // いったん予約取り消し
144 self::cancel( $prev_id ); 144 self::cancel( $prev_id );
145 // 再予約 145 // 再予約
146 self::custom( 146 self::custom(
147 $prev_starttime, // 開始時間Datetime型 147 $prev_starttime, // 開始時間Datetime型
148 $prev_endtime, // 終了時間Datetime型 148 $prev_endtime, // 終了時間Datetime型
149 $prev_channel_id, // チャンネルID 149 $prev_channel_id, // チャンネルID
150 $prev_title, // タイトル 150 $prev_title, // タイトル
151 $prev_description, // 概要 151 $prev_description, // 概要
170 throw new Exception( "重複予約があります" ); 170 throw new Exception( "重複予約があります" );
171 } 171 }
172 } 172 }
173 // チューナー番号 173 // チューナー番号
174 $tuner = $battings; 174 $tuner = $battings;
175 175
176 // 改めてdurationをチェックしなおす 176 // 改めてdurationをチェックしなおす
177 if( $duration < ($settings->former_time + 60) ) { // 60秒以下の番組は弾く 177 if( $duration < ($settings->former_time + 60) ) { // 60秒以下の番組は弾く
178 throw new Exception( "終わりつつある/終わっている番組です" ); 178 throw new Exception( "終わりつつある/終わっている番組です" );
179 } 179 }
180 180
181 181
182 // ここからファイル名生成 182 // ここからファイル名生成
183 /* 183 /*
184 %TITLE% 番組タイトル 184 %TITLE% 番組タイトル
185 %ST% 開始日時(ex.200907201830) 185 %ST% 開始日時(ex.200907201830)
186 %ET% 終了日時 186 %ET% 終了日時
197 %DURATION% 録画時間(秒) 197 %DURATION% 録画時間(秒)
198 */ 198 */
199 199
200 $day_of_week = array( "日","月","火","水","木","金","土" ); 200 $day_of_week = array( "日","月","火","水","木","金","土" );
201 $filename = $settings->filename_format; 201 $filename = $settings->filename_format;
202 202
203 // あると面倒くさそうな文字を全部_に 203 // あると面倒くさそうな文字を全部_に
204 $fn_title = mb_ereg_replace("[ \./\*:<>\?\\|()\'\"&]","_", trim($title) ); 204 $fn_title = mb_ereg_replace("[ \./\*:<>\?\\|()\'\"&]","_", trim($title) );
205 205
206 // %TITLE% 206 // %TITLE%
207 $filename = str_replace("%TITLE%", $fn_title, $filename); 207 $filename = str_replace("%TITLE%", $fn_title, $filename);
208 // %ST% 開始日時 208 // %ST% 開始日時
209 $filename = str_replace("%ST%",date("YmdHis", $start_time), $filename ); 209 $filename = str_replace("%ST%",date("YmdHis", $start_time), $filename );
210 // %ET% 終了日時 210 // %ET% 終了日時
229 $filename = str_replace("%MIN%",date("i", $start_time), $filename ); 229 $filename = str_replace("%MIN%",date("i", $start_time), $filename );
230 // %SEC% 開始秒 230 // %SEC% 開始秒
231 $filename = str_replace("%SEC%",date("s", $start_time), $filename ); 231 $filename = str_replace("%SEC%",date("s", $start_time), $filename );
232 // %DURATION% 録画時間(秒) 232 // %DURATION% 録画時間(秒)
233 $filename = str_replace("%DURATION%","".$duration, $filename ); 233 $filename = str_replace("%DURATION%","".$duration, $filename );
234 234
235 // 文字コード変換 235 // 文字コード変換
236 if( defined("FILESYSTEM_ENCODING") ) { 236 if( defined("FILESYSTEM_ENCODING") ) {
237 $filename = mb_convert_encoding( $filename, FILESYSTEM_ENCODING, "UTF-8" ); 237 // $filename = mb_convert_encoding( $filename, FILESYSTEM_ENCODING, "UTF-8" );
238 $filename = mb_convert_encoding( $filename, FILESYSTEM_ENCODING, "auto" );
238 } 239 }
239 $filename .= $RECORD_MODE["$mode"]['suffix']; 240 $filename .= $RECORD_MODE["$mode"]['suffix'];
240 $thumbname = $filename.".jpg"; 241 $thumbname = $filename.".jpg";
241 242
242 // サムネール 243 // サムネール
243 $gen_thumbnail = INSTALL_PATH."/gen-thumbnail.sh"; 244 $gen_thumbnail = INSTALL_PATH."/gen-thumbnail.sh";
244 if( defined("GEN_THUMBNAIL") ) 245 if( defined("GEN_THUMBNAIL") )
245 $gen_thumbnail = GEN_THUMBNAIL; 246 $gen_thumbnail = GEN_THUMBNAIL;
246 247
247 // ファイル名生成終了 248 // ファイル名生成終了
248 249
249 // 予約レコードを埋める 250 // 予約レコードを埋める
250 $rrec = new DBRecord( RESERVE_TBL ); 251 $rrec = new DBRecord( RESERVE_TBL );
251 $rrec->channel_disc = $crec->channel_disc; 252 $rrec->channel_disc = $crec->channel_disc;
252 $rrec->channel_id = $crec->id; 253 $rrec->channel_id = $crec->id;
253 $rrec->program_id = $program_id; 254 $rrec->program_id = $program_id;
260 $rrec->endtime = toDatetime( $end_time ); 261 $rrec->endtime = toDatetime( $end_time );
261 $rrec->path = $filename; 262 $rrec->path = $filename;
262 $rrec->autorec = $autorec; 263 $rrec->autorec = $autorec;
263 $rrec->mode = $mode; 264 $rrec->mode = $mode;
264 $rrec->reserve_disc = md5( $crec->channel_disc . toDatetime( $start_time ). toDatetime( $end_time ) ); 265 $rrec->reserve_disc = md5( $crec->channel_disc . toDatetime( $start_time ). toDatetime( $end_time ) );
265 266
266 // 予約実行 267 // 予約実行
267 $cmdline = $settings->at." ".date("H:i m/d/Y", $at_start); 268 $cmdline = $settings->at." ".date("H:i m/d/Y", $at_start);
268 $descriptor = array( 0 => array( "pipe", "r" ), 269 $descriptor = array( 0 => array( "pipe", "r" ),
269 1 => array( "pipe", "w" ), 270 1 => array( "pipe", "w" ),
270 2 => array( "pipe", "w" ), 271 2 => array( "pipe", "w" ),
278 "THUMB" => INSTALL_PATH.$settings->thumbs."/".$thumbname, 279 "THUMB" => INSTALL_PATH.$settings->thumbs."/".$thumbname,
279 "FORMER" => "".$settings->former_time, 280 "FORMER" => "".$settings->former_time,
280 "FFMPEG" => "".$settings->ffmpeg, 281 "FFMPEG" => "".$settings->ffmpeg,
281 "SID" => $crec->sid, 282 "SID" => $crec->sid,
282 ); 283 );
283 284
284 // ATで予約する 285 // ATで予約する
285 $process = proc_open( $cmdline , $descriptor, $pipes, INSTALL_PATH.$settings->spool, $env ); 286 $process = proc_open( $cmdline , $descriptor, $pipes, INSTALL_PATH.$settings->spool, $env );
286 if( is_resource( $process ) ) { 287 if( is_resource( $process ) ) {
287 fwrite($pipes[0], $settings->sleep." ".$sleep_time."\n" ); 288 fwrite($pipes[0], $settings->sleep." ".$sleep_time."\n" );
288 fwrite($pipes[0], DO_RECORD . "\n" ); 289 fwrite($pipes[0], DO_RECORD . "\n" );
291 fwrite($pipes[0], $gen_thumbnail."\n" ); 292 fwrite($pipes[0], $gen_thumbnail."\n" );
292 } 293 }
293 fclose($pipes[0]); 294 fclose($pipes[0]);
294 // 標準エラーを取る 295 // 標準エラーを取る
295 $rstring = stream_get_contents( $pipes[2]); 296 $rstring = stream_get_contents( $pipes[2]);
296 297
297 fclose( $pipes[2] ); 298 fclose( $pipes[2] );
298 proc_close( $process ); 299 proc_close( $process );
299 } 300 }
300 else { 301 else {
301 $rrec->delete(); 302 $rrec->delete();
328 } 329 }
329 throw $e; 330 throw $e;
330 } 331 }
331 } 332 }
332 // custom 終了 333 // custom 終了
333 334
334 // 取り消し 335 // 取り消し
335 public static function cancel( $reserve_id = 0, $program_id = 0 ) { 336 public static function cancel( $reserve_id = 0, $program_id = 0 ) {
336 $settings = Settings::factory(); 337 $settings = Settings::factory();
337 $rec = null; 338 $rec = null;
338 339
339 try { 340 try {
340 if( $reserve_id ) { 341 if( $reserve_id ) {
341 $rec = new DBRecord( RESERVE_TBL, "id" , $reserve_id ); 342 $rec = new DBRecord( RESERVE_TBL, "id" , $reserve_id );
342 } 343 }
343 else if( $program_id ) { 344 else if( $program_id ) {