Mercurial > epgrec.yaz
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 ) { |