OSDN Git Service

add awesome features.
authorgn64_jp <gn64_jp@4e526526-5e11-4fc0-8910-f8fd03428081>
Sat, 5 Dec 2009 08:43:36 +0000 (08:43 +0000)
committergn64_jp <gn64_jp@4e526526-5e11-4fc0-8910-f8fd03428081>
Sat, 5 Dec 2009 08:43:36 +0000 (08:43 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/rec10@299 4e526526-5e11-4fc0-8910-f8fd03428081

rectool/trunk/rectool.pl

index 3966622..68b8b66 100755 (executable)
@@ -24,17 +24,15 @@ my $tz = DateTime::TimeZone->new( name => 'local' );
 my $hires = Time::HiRes::time();
 
 my $cfg = new Config::Simple;
-$cfg->read( 'config.ini' );
-my $sql = $cfg->param( 'db.db' );
-
-if ( $sql eq 'SQLite' ) {
-       $dbh = DBI->connect("dbi:SQLite:dbname=ch.db", undef, undef, {
-               AutoCommit => 1,
-               RaiseError => 1,
-       });
-       $SQL{'SUBSTR'} = 'SUBSTR(start, 0, 9)';
+if ( -e '/etc/rec10.conf' ) {
+       $cfg->read( '/etc/rec10.conf' );
+}
+else {
+       $cfg->read( 'config.ini' );
 }
 
+my $sql = $cfg->param( 'db.db' );
+
 if ( $sql eq 'MySQL' ) {
        my $name = $cfg->param( 'db.mysql_dbname' );
        my $host = $cfg->param( 'db.mysql_host' );
@@ -46,7 +44,6 @@ if ( $sql eq 'MySQL' ) {
                RaiseError => 1,
        });
        $dbh->do( 'SET NAMES utf8' );
-       $SQL{'SUBSTR'} = 'SUBSTRING(start, 1, 8)';
 }
 
 my $HTML;
@@ -74,30 +71,46 @@ EOM
 
 $q = new CGI::Minimal;
 $mode = $q->param( 'mode' );
-
-$display = $q->param( 'ch' );
-$start   = $q->param( 'start' );
-$stop    = $q->param( 'stop' );
-$key     = $q->param( 'key' );
-@id      = $q->param( 'id' );
+$mode_sub = $q->param( 'mode_sub' );
 
 %type = (
-       'res'         => '一回限定',
-       'rec'         => '最終段階',
-       'key'         => '当日検索',
-       'keyevery'    => '隔日検索',
-       'tsrecording' => '録画途中',
-       'tsfin'       => '録画終了',
-       'tsmiss'      => '録画失敗',
-       'b252ts'      => '解読予約',
-       'tsdecoding'  => '解読途中',
-       'ts2avi'      => '縁故予約',
-       'local'       => '縁故於鯖',
-       'grid'        => '縁故於網',
-       'fin_local'   => '縁故完了',
-       'end'         => '録画終了',
+       'search_everyday'         => '隔日検索',
+       'search_today'            => '当日検索',
+       'reserve_flexible'        => '浮動予約',
+       'reserve_fixed'           => '確定予約',
+
+       'reserve_running'         => '録画途中',
+
+       'convert_b25_ts'          => '解読予約',
+       'convert_b25_ts_running'  => '解読途中',
+       'convert_b25_ts_miss'     => '解読失敗',
+
+       'convert_ts_mp4'          => '縁故予約',
+       'convert_ts_mp4_running'  => '縁故於鯖',
+       'convert_ts_mp4_network'  => '縁故於網',
+       'convert_ts_mp4_finished' => '縁故完了',
+
+       'convert_avi_mkv'         => '変換旧露',
+       'convert_avi_mp4'         => '変換旧四',
+       'convert_mkv_mp4'         => '変換露四',
+
+       'auto_suggest_dec'        => '予測解読',
+       'auto_suggest_enc'        => '予測縁故',
+       'auto_suggest_a24'        => '予測旧四',
+       'auto_suggest_m24'        => '予測露四',
+
+       'move_end'                => '移動完了',
 );
 
+%type_suggest = (
+       'auto_suggest_dec' => 'convert_b25_ts',
+       'auto_suggest_enc' => 'convert_ts_mp4',
+       'auto_suggest_a24' => 'convert_avi_mp4',
+       'auto_suggest_m24' => 'convert_mkv_mp4',
+);
+
+$type_user_made = "( 'search_everyday', 'search_today', 'reserve_flexible', 'reserve_fixed', 'reserve_running' )";
+
 %category = (
        'etc'         => 'その他', 
        'news'        => 'ニュース・報道', 
@@ -133,19 +146,12 @@ EOM
        $forward_order = $order eq 'btime' ? '' : '&amp;order=id';
 
        my $ary_ref = $dbh->selectall_arrayref(
-               "SELECT id, type, rectime.chtxt, chdata.ontv, ch.display, title, btime, etime, opt, deltaday, deltatime 
-               FROM rectime 
-               INNER JOIN chdata ON rectime.chtxt = chdata.chtxt 
-               INNER JOIN ch     ON chdata.ontv   = ch.channel 
-               ORDER BY $order");
-
-       $HTML .= qq {<div style="font-size: 10pt; float: left">\n};     my $ary_ref = $dbh->selectall_arrayref(
-               "SELECT id, type, rectime.chtxt, chdata.ontv, ch.display, title, btime, etime, opt, deltaday, deltatime 
-               FROM rectime 
-               INNER JOIN chdata ON rectime.chtxt = chdata.chtxt 
-               INNER JOIN ch     ON chdata.ontv   = ch.channel 
+               "SELECT id, type, epg_ch.chtxt, epg_ch.ontv, epg_ch.chname, title, btime, etime, opt, deltaday, deltatime 
+               FROM timeline 
+               INNER JOIN epg_ch ON timeline.chtxt = epg_ch.chtxt 
                ORDER BY $order");
 
+       $HTML .= qq {<div style="font-size: 10pt; float: left">\n};
        $HTML .= qq {<form method="get" action="rectool.pl">\n};
        $HTML .= qq {<div>\n};
        $HTML .= qq {<input type="hidden" name="mode" value="change">\n};
@@ -165,66 +171,60 @@ EOM
        foreach my $line ( @{ $ary_ref } ) {
 
                $type = $type{$line->[1]} || $line->[1];
-               if    ( $line->[1] eq 'key' || $line->[1] eq 'keyevery' ) {
+               if    ( $line->[1] =~ /^search/ ) {
                        $type = qq {<span style="color: #800080">$type</span>};
-                       $line->[9]  = qq {<span style="color: #FF0000">空</span>} if ( !$line->[9] && $line->[1] eq 'keyevery' );
+                       $line->[9]  = qq {<span style="color: #FF0000">空</span>} if ( !$line->[9] && $line->[1] eq 'search_everyday' );
                        $line->[10] = qq {<span style="color: #FF0000">空</span>} if ( !$line->[10] );
                }
-               elsif ( $line->[1] eq 'res' || $line->[1] eq 'rec' ) {
-                       $type = qq {<span style="color: #A0A000">$type</span>};
-               }
-               elsif ( $line->[1] eq 'tsrecording' ) {
+               elsif ( $line->[1] eq 'reserve_running' ) {
                        $type = qq {<span style="color: #FFA000">$type</span>};
                }
-               elsif ( $line->[1] eq 'b252ts' || $line->[1] eq 'ts2avi' ) {
+               elsif ( $line->[1] =~ /^reserve/ ) {
+                       $type = qq {<span style="color: #A0A000">$type</span>};
+               }
+               elsif ( $line->[1] eq 'convert_b25_ts' || $line->[1] eq 'convert_b25_ts' ) {
                        $type = qq {<span style="color: #404040">$type</span>};
                }
-               elsif ( $line->[1] eq 'tsdecoding' ) {
+               elsif ( $line->[1] eq 'convert_b25_ts_running' ) {
                        $type = qq {<span style="color: #C04040">$type</span>};
                }
-               elsif ( $line->[1] eq 'local' ) {
+               elsif ( $line->[1] eq 'convert_ts_mp4_running' ) {
                        $type = qq {<span style="color: #008080">$type</span>};
                }
                else {
                        $type = qq {<span style="color: #A0A0A0">$type</span>};
                }
-               $display = $q->url_encode( $line->[4] );
+               $chname_encoded = $q->url_encode( $line->[4] );
                $line->[5] = 'タイトルなし' if ( !$line->[5] );
-               my @unix_6 = $line->[6] =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
-               my $unix_6 = DateTime->new(
-                       year => $unix_6[0], month  => $unix_6[1], day    => $unix_6[2],
-                       hour => $unix_6[3], minute => $unix_6[4], second => $unix_6[5], 
-                       time_zone => $tz
-               );
-               my @unix_7 = $line->[7] =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
-               my $unix_7 = DateTime->new(
-                       year => $unix_7[0], month  => $unix_7[1], day    => $unix_7[2],
-                       hour => $unix_7[3], minute => $unix_7[4], second => $unix_7[5], 
-                       time_zone => $tz
-               );
+               my $unix_6 = str2datetime( $line->[6] );
+               my $unix_7 = str2datetime( $line->[7] );
 
                my $btime = $unix_6->strftime( '%Y%m%d%H%M%S' );
                my $etime = $unix_7->strftime( '%Y%m%d%H%M%S' );
-               if ( $extra and $line->[1] =~ /key|res/ ) {
+               if ( $extra and $line->[1] =~ /^search_|^reserve_/ ) {
                        my @ary = $dbh->selectrow_array(
-                               "SELECT title, exp FROM tv 
+                               "SELECT title, exp FROM epg_timeline 
                                WHERE channel = '$line->[3]' 
                                AND start = '$btime' 
                                AND stop  = '$etime' ");
-                       $ary[0] = '説明' if ( $line->[1] eq 'res' );
+
                        if ( $ary[0] ) {
                                $ary[0] =~ s/無料≫//;
-                               if ( $line->[1] ne 'res' && $ary[0] ne $line->[5] ) {
+
+                               if ( $ary[0] ne $line->[5] ) {
                                        my $count = $ary[0] =~ s/\Q$line->[5]\E//;
                                        if ( !$count ) {
                                                $ary[0] = qq {<span style="color: #FF4000">$ary[0]</span>};
                                        }
                                }
+                               else {
+                                       $ary[0] = '説明';
+                               }
+
                                if ( $ary[1] ) {
                                        $line->[11] = qq {<div style="float: right; cursor: help" title="$ary[1]">$ary[0]</div>};
                                }
                                else {
-                                       # $line->[11] = qq {<span style="float: right; color: #FF0000">該当なし</span>};
                                        $line->[11] = qq {<span style="float: right">説明なし</span>};
                                }
                        }
@@ -234,7 +234,8 @@ EOM
                        }
                }
 
-               my $begin = $unix_6->strftime( '%m/%d %H:%M' );
+               my $begin = $unix_6->strftime( '%m/%d(%a) %H:%M' );
+               utf8::encode( $begin );
                my $end;
                if ( $unix_6->month == $unix_7->month && $unix_6->day == $unix_7->day )
                {
@@ -257,7 +258,7 @@ EOM
 
                my $hr;
                if ( 
-                       $line->[1] eq 'tsrecording' 
+                       $line->[1] eq 'reserve_running' 
                                &&
                        $unix_6->epoch <= time && time <= $unix_7->epoch
                )
@@ -273,12 +274,11 @@ EOM
                $HTML .= qq {<td><input type="checkbox" name="id" value="$line->[0]"></td>\n};
                $HTML .= qq {<td>$line->[0]</td>\n};
                $HTML .= qq {<td>$type</td>\n};
-               $HTML .= qq {<td><a href="rectool.pl?mode=program&amp;ch=$display">$line->[2]</a></td>\n};
+               $HTML .= qq {<td><a href="rectool.pl?mode=program&amp;chname=$chname_encoded">$line->[2]</a></td>\n};
                $HTML .= qq {<td align="left" style="white-space: normal">$line->[5]$line->[11]</td>\n};
                $HTML .= qq {<td>$begin</td>\n<td>$end</td>\n};
                $HTML .= qq {<td>$hr$diff</td>\n};
                $HTML .= qq {<td>$line->[8]</td>\n<td>$line->[9]</td>\n<td>$line->[10]</td>\n};
-               # $HTML .= qq {<td>$line->[11]</td>\n} if ( $extra );
                $HTML .= qq {</tr>\n};
        }
        $HTML .= qq {</table>\n};
@@ -325,7 +325,7 @@ if ( $mode eq 'graph' ) {
                        $svg->text( 'x' => $_ * 30 + 65, 'y' => 15, 
                                style => { 'text-anchor' => 'middle' } )
                                ->cdata( sprintf( '%02d', $_ ) ) if ( $_ < $hours );
-#                      $svg->line( ); # can't use when required
+                       # $svg->line( ); # can't use when required
                        $svg->tag( 'line', x1 => $_ * 30 + 50, x2 => $_ * 30 + 50, y1 => 30, y2 => $tuner{all} * 20 + 20, 
                                style => { stroke => 'gray' } );
                }
@@ -342,10 +342,10 @@ if ( $mode eq 'graph' ) {
                foreach my $bctype ( 'te%', '_s%' ) {
                        my $tuner = $bctype eq 'te%' ? $tuner{terrestrial} : $tuner{satellite};
                        my $ary_ref = $dbh->selectall_arrayref(
-                               "SELECT id, type, rectime.chtxt, title, btime, etime, opt FROM rectim
-                               INNER JOIN chdata ON rectime.chtxt = chdata.chtxt 
-                               WHERE chdata.bctype LIKE '$bctype' 
-                               AND type IN ( 'rec', 'res', 'key', 'keyevery', 'tsrecording' ) 
+                               "SELECT id, type, timeline.chtxt, title, btime, etime, opt FROM timelin
+                               INNER JOIN epg_ch ON timeline.chtxt = epg_ch.chtxt 
+                               WHERE epg_ch.bctype LIKE '$bctype' 
+                               AND type IN $type_user_made 
                                AND 
                                (
                                        '$graph_bgn 00:00' <= btime AND btime <  '$graph_end 00:00'
@@ -365,10 +365,10 @@ if ( $mode eq 'graph' ) {
                                $end   = $line->[5];
 
                                my $ary = $dbh->selectall_arrayref( 
-                                       "SELECT id, type, rectime.chtxt, title, btime, etime, opt FROM rectim
-                                       INNER JOIN chdata ON rectime.chtxt = chdata.chtxt 
-                                       WHERE chdata.bctype LIKE '$bctype' 
-                                       AND type IN ( 'rec', 'res', 'key', 'keyevery', 'tsrecording' ) 
+                                       "SELECT id, type, timeline.chtxt, title, btime, etime, opt FROM timelin
+                                       INNER JOIN epg_ch ON timeline.chtxt = epg_ch.chtxt 
+                                       WHERE epg_ch.bctype LIKE '$bctype' 
+                                       AND type IN $type_user_made 
                                        AND NOT 
                                        ( 
                                                ( etime <= '$begin' ) 
@@ -427,16 +427,15 @@ if ( $mode eq 'graph' ) {
        {
                $HTML =~ s/%HTML_TITLE_OPT%/ - Schedule Viewer - Graphical/;
                $HTML .= qq {<div style="float: left">\n};
-#              $base64 = encode_base64( $svg->xmlify );
-#              $HTML .= qq {<object data="data:image/svg+xml;base64,$base64">\n</object>\n};
+               # $base64 = encode_base64( $svg->xmlify );
+               # $HTML .= qq {<object data="data:image/svg+xml;base64,$base64">\n</object>\n};
                $HTML .= qq {予約状況一覧です。T1,T2は地上波、S1,S2はBS/CS、赤はアニメ、緑はHD、青は2 passを示しています。<br>\n};
                $HTML .= qq {SVGが利用可能なブラウザでご覧ください。<br>\n};
 
                $ary_ref = $dbh->selectcol_arrayref(
-#                      "SELECT DISTINCT SUBSTR( btime, 0, 11 ) 
                        "SELECT DISTINCT DATE( btime ) 
-                       FROM rectim
-                       WHERE type in ( 'rec', 'res', 'key', 'keyevery', 'tsrecording' ) 
+                       FROM timelin
+                       WHERE type in $type_user_made 
                        ORDER BY btime"
                );
                foreach my $date ( @{ $ary_ref } ) {
@@ -445,12 +444,11 @@ if ( $mode eq 'graph' ) {
                        utf8::encode( $dn );
                        $HTML .= qq {$date[1]/$date[2]($dn)の予約状況<br>\n};
                        $HTML .= qq {<object type="image/svg+xml" data="rectool.pl?mode=graph&amp;graph=$date" width="820">\n};
-                       # width=821 height=121>\n};
                        $HTML .= qq {SVG Image $date\n</object>\n<br>\n};
 
                        $date2 = Date::Simple->new( @date )->next->format('%Y-%m-%d');
                        my $ary_ref = $dbh->selectall_arrayref(
-                               "SELECT chtxt, title, btime, etime FROM rectim
+                               "SELECT chtxt, title, btime, etime FROM timelin
                                WHERE '$date 00:00' <= btime AND etime <= '$date2 01:00'
                                ORDER BY btime"
                        );
@@ -466,6 +464,8 @@ if ( $mode eq 'graph' ) {
 }
 
 if ( $mode eq 'edit' ) {
+       my $id = $q->param( 'id' );
+
        $HTML =~ s/%HTML_TITLE_OPT%/ - Schedule Editor/;
        $HTML .= qq {<div style="float: left">\n};
 
@@ -476,11 +476,11 @@ if ( $mode eq 'edit' ) {
                function setType(value){
                        var index = document.reserve.type.selectedIndex;
                        var value = document.reserve.type[index].value;
-                       if ( value == 'keyevery' ) {
+                       if ( value == 'search_everyday' ) {
                                document.reserve.deltaday.value  = 7;
                                document.reserve.deltatime.value = 3;
                        }
-                       if ( value == 'ts2avi' || value == 'b252ts' ){
+                       if ( value == 'convert_b25_ts' || value == 'convert_ts_mp4' ){
                                var date       = new Date();
                                var dateFormat = new DateFormat("yyyy-MM-dd HH:mm:ss");
                                var minutes    = date.getMinutes();
@@ -495,6 +495,12 @@ if ( $mode eq 'edit' ) {
                        document.reserve.begin.value = start;
                        document.reserve.end.value   = stop;
                }
+               function shiftEndTime(value){
+                       var dateFormat = new DateFormat("yyyy-MM-dd HH:mm:ss");
+                       var date = dateFormat.parse(document.reserve.end.value || document.reserve.begin.value);
+                       date.setSeconds( date.getSeconds() + value );
+                       document.reserve.end.value = dateFormat.format(date);
+               }
                </script>
 EOM
        $script =~ s/^\t{2}//gm;
@@ -502,27 +508,23 @@ EOM
 
        $HTML .= "スケジュール編集画面です。<br>\n";
        $HTML .= "実装がとても適当なので、利用には細心の注意を払ってください。<br>\n<br>\n";
-       if ( $id[0] ) {
-               @reserve = $dbh->selectrow_array(
-                       "SELECT id, type, chtxt, title, btime, etime, deltaday, deltatime, opt 
-                       FROM rectime 
-                       WHERE id = $id[0]"
-               );
+       if ( $id ) {
+               &parse_program();
                $button_bgn = $button_end = '';
        }
        else {
-               $reserve[1] = 'res';
-               $datetime_now = DateTime->now( time_zone => $tz )->set_second( 0 )->strftime( '%Y-%m-%d %H:%M:%S' );
+               $type = 'reserve_flexible';
+               $datetime_now = DateTime->now( time_zone => $tz )->set_second( 0 )->add( minutes => 1)->strftime( '%Y-%m-%d %H:%M:%S' );
                $button_bgn = qq{<button type="button" onClick="document.reserve.begin.value='$datetime_now'">現在</button>\n<br>\n};
-               $button_end = qq{<button type="button" onClick="document.reserve.end.value=document.reserve.begin.value">一致</button>};
+               $button_end = 
+                        qq{<button type="button" onClick="document.reserve.end.value=document.reserve.begin.value">一致</button>}
+                       .qq{<button type="button" onClick="shiftEndTime(300);">+5m</button>}
+                       .qq{<button type="button" onClick="shiftEndTime(1800);">+30m</button>};
        }
 
        if ( $q->param( 'suggest' ) eq 'auto' ) {
-               require Encode;
-               require Text::Ngram;
-
-               my @btime = $reserve[4] =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
-               my @etime = $reserve[5] =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
+               my @btime = $begin =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
+               my @etime = $end   =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
                my $btime = DateTime->new(
                        year => $btime[0], month  => $btime[1], day    => $btime[2],
                        hour => $btime[3], minute => $btime[4], second => $btime[5], 
@@ -531,36 +533,7 @@ EOM
                        year => $etime[0], month  => $etime[1], day    => $etime[2],
                        hour => $etime[3], minute => $etime[4], second => $etime[5], 
                );
-               $btime_bgn = $btime->clone;
-               $btime_end = $btime->clone;
-               $etime_bgn = $etime->clone;
-               $etime_end = $etime->clone;
-               $btime_bgn->subtract( hours => $reserve[7] );
-               $btime_end->add(      hours => $reserve[7] );
-               $etime_bgn->subtract( hours => $reserve[7] );
-               $etime_end->add(      hours => $reserve[7] );
-               $btime_bgn = $btime_bgn->strftime( '%Y%m%d%H%M%S' );
-               $btime_end = $btime_end->strftime( '%Y%m%d%H%M%S' );
-               $etime_bgn = $etime_bgn->strftime( '%Y%m%d%H%M%S' );
-               $etime_end = $etime_end->strftime( '%Y%m%d%H%M%S' );
-
-               my $ontv = $dbh->selectrow_array( "SELECT ontv FROM chdata WHERE chtxt = '$reserve[2]' " );
-               $ary_ref = $dbh->selectall_arrayref(
-                       "SELECT start, stop, title, exp 
-                       FROM tv 
-                       WHERE channel = '$ontv' 
-                       AND start BETWEEN '$btime_bgn' AND '$btime_end' 
-                       AND stop  BETWEEN '$etime_bgn' AND '$etime_end' "
-               );
-
-               my %hash;
-               my $hash_r = Text::Ngram::ngram_counts( Encode::decode_utf8( $reserve[3] ), 2 ); # bi-gram
-               foreach my $program ( @{$ary_ref} ) {
-                       my $hash_k = Text::Ngram::ngram_counts( Encode::decode_utf8( $program->[2] ), 2 );
-                       my $point;
-                       map $point += $hash_k->{$_}, keys %{$hash_r};
-                       push @{$hash{$point}}, $program if ( $point );
-               }
+               my %hash = &sqlgetsuggested( $btime, $etime );
 
                $HTML .= qq {可能性のある番組<br>\n};
                $HTML .= qq {<table summary="suggesttable" border=1 cellspacing=0>\n<tr>\n};
@@ -586,15 +559,16 @@ EOM
                $HTML .= qq {</table>\n<br>\n};
        }
 
-       my $len = length $reserve[0];
+       my $len = length $id;
        $HTML .= qq {<form method="get" action="rectool.pl" name="reserve">\n};
        $HTML .= qq {<input type="hidden" name="mode" value="change">\n};
-       $HTML .= qq {<input type="hidden" name="id" value="$reserve[0]">\n};
-       $HTML .= qq {ID\n<input type="text" name="id" value="$reserve[0]" size=$len disabled>\n};
+       $HTML .= qq {<input type="hidden" name="mode_sub" value="update">\n};
+       $HTML .= qq {<input type="hidden" name="id" value="$id">\n};
+       $HTML .= qq {ID\n<input type="text" name="id" value="$id" size=$len disabled>\n};
        $HTML .= qq {タイプ\n<select name="type" onChange="setType();">\n};
        while ( my ($key, $value) = each %type ) {
-               next if ( $key !~ /^rec|res|key|ts2avi|b252ts|$reserve[1]/ );
-               if ( $key eq $reserve[1] ) {
+               next if ( $key !~ /^search|^reserve|^convert_b25_ts$|^convert_ts_mp4$|^$type$/ );
+               if ( $key eq $type ) {
                        $HTML .= qq {<option value="$key" selected>$value</option>\n};
                }
                else {
@@ -602,29 +576,33 @@ EOM
                }
        }
        $HTML .= qq {</select>\n};
-       $HTML .= qq {チャンネル\n<select name="ch">\n};
+       $HTML .= qq {チャンネル\n<select name="chtxt">\n};
        $ary_ref = $dbh->selectall_arrayref(
-               "SELECT display, chtxt FROM ch INNER JOIN chdata ON ch.channel = chdata.ontv"
+               "SELECT chname, chtxt FROM epg_ch"
        );
-       foreach my $ch ( @{$ary_ref} ) {
-               if ( $ch->[1] eq $reserve[2] ) {
-                       $HTML .= qq {<option value="$ch->[1]" selected>$ch->[0]</option>\n};
+       foreach my $line ( @{$ary_ref} ) {
+               if ( $line->[1] eq $chtxt ) {
+                       $HTML .= qq {<option value="$line->[1]" selected>$line->[0]</option>\n};
                }
                else {
-                       $HTML .= qq {<option value="$ch->[1]">$ch->[0]</option>\n};
+                       $HTML .= qq {<option value="$line->[1]">$line->[0]</option>\n};
                }
        }
        $HTML .= qq {</select><br>\n};
-       $HTML .= qq {タイトル\n<input type="text" name="title"     value="$reserve[3]" size=64><br>\n};
-       $HTML .= qq {開始時刻\n<input type="text" name="begin"     value="$reserve[4]" maxlength=19 size=24>\n}.$button_bgn;
-       $HTML .= qq {終了時刻\n<input type="text" name="end"       value="$reserve[5]" maxlength=19 size=24>\n}.$button_end."<br>\n";
-       $HTML .= qq {隔日周期\n<input type="text" name="deltaday"  value="$reserve[6]" maxlength=2  size=2>\n};
-       $HTML .= qq {時刻誤差\n<input type="text" name="deltatime" value="$reserve[7]" maxlength=2  size=2>\n};
-       $HTML .= qq {オプション\n<input type="text" name="opt"     value="$reserve[8]">\n};
+       $HTML .= qq {タイトル\n<input type="text" name="title" value="$title" size=64><br>\n};
+       $HTML .= qq {開始時刻\n<input type="text" name="begin" value="$begin" maxlength=19 size=24>\n};
+       $HTML .= $button_bgn;
+       $HTML .= qq {終了時刻\n<input type="text" name="end" value="$end" maxlength=19 size=24>\n};
+       $HTML .= $button_end . "<br>\n";
+       $HTML .= qq {隔日周期\n<input type="text" name="deltaday" value="$deltaday" maxlength=2  size=2 >\n};
+       $HTML .= qq {時刻誤差\n<input type="text" name="deltatime" value="$deltatime" maxlength=2  size=2 >\n};
+       $HTML .= qq {オプション\n<input type="text" name="opt" value="$opt">\n};
        $HTML .= qq {<input type="submit" name="update" value="更新">\n</form>\n};
 }
 
 if ( $mode eq 'change' ) {
+       @id     = $q->param( 'id' );
+
        $HTML =~ s/%HTML_TITLE_OPT%/ - Change/;
        $HTML .= qq {<div style="float: left">\n};
 
@@ -632,28 +610,17 @@ if ( $mode eq 'change' ) {
        {
                if ( @id ) {
                        foreach my $id ( @id ) {
-                               $dbh->do( "DELETE FROM rectime WHERE id = '$id'" );
+                               $dbh->do( "DELETE FROM timeline WHERE id = '$id'" );
                        }
                        $HTML .= "削除しました。<br>\n5秒後に予約確認画面に移動します。<br>\n";
                        $HTML =~ s|%REFRESH%|<meta http-equiv="refresh" content="5; url=rectool.pl?mode=schedule">|;
                        goto end;
                }
        }
-       if ( $q->param( 'edit' ) )
-       {
-               if ( $q->param( 'edit' ) eq '編集(要JS)' ) {
-                       $HTML .= "スケジュール編集画面に移動します。<br>\n";
-                       $HTML =~ s|%REFRESH%|<meta http-equiv="refresh" content="0; url=../rec10web/rec10web.py?exec=edit:$id[0]">|;
-                       goto end;
-               }
-               else {
-                       goto end;
-               }
-       }
        if ( $q->param( 'update' ) )
        {
                $type      = $q->param( 'type' );
-               $chtxt     = $q->param( 'ch' );
+               $chtxt     = $q->param( 'chtxt' );
                $title     = $q->param( 'title' );
                $begin     = $q->param( 'begin' );
                $end       = $q->param( 'end' );
@@ -661,9 +628,9 @@ if ( $mode eq 'change' ) {
                $deltatime = $q->param( 'deltatime' );
                $opt       = $q->param( 'opt' );
                $id        = $id[0];
-               if ( $id[0] ) {
+               if ( $id ) {
                        $dbh->do( 
-                               "UPDATE rectime SET type = '$type', chtxt = '$chtxt', title = '$title', 
+                               "UPDATE timeline SET type = '$type', chtxt = '$chtxt', title = '$title', 
                                btime = '$begin', etime = '$end', 
                                deltaday = '$deltaday', deltatime = '$deltatime', opt = '$opt' 
                                WHERE id = '$id'" 
@@ -671,7 +638,7 @@ if ( $mode eq 'change' ) {
                }
                else {
                        $dbh->do( 
-                               "INSERT INTO rectime ( type, chtxt, title, btime, etime, deltaday, deltatime, opt ) 
+                               "INSERT INTO timeline ( type, chtxt, title, btime, etime, deltaday, deltatime, opt ) 
                                VALUES ( '$type', '$chtxt', '$title', '$begin', '$end', '$deltaday', '$deltatime', '$opt' )" 
                        );
                }
@@ -679,70 +646,167 @@ if ( $mode eq 'change' ) {
                $HTML =~ s|%REFRESH%|<meta http-equiv="refresh" content="5; url=rectool.pl?mode=schedule">|;
                goto end;
        }
+       if ( $mode_sub eq 'proc' ) {
+               my $type  = $q->param( 'type' );
+               my $chtxt = $q->param( 'chtxt' ) || 'nhk-k';
+               my $title = $q->param( 'title' );
+               my @opt   = $q->param( 'opt' );
+               my $opt   = join '', @opt;
+
+               my $datetime_now = DateTime->now( time_zone => $tz )->set_second( 0 )->add( minutes => 10);
+               my $sql_type = $type_suggest{$type};
+               my $begin = $datetime_now->strftime( '%Y-%m-%d %H:%M:%S' );
+               $datetime_now = $datetime_now->add( minutes => 60 );
+               my $end = $datetime_now->strftime( '%Y-%m-%d %H:%M:%S' );
+
+               $dbh->do( 
+                       "INSERT INTO timeline ( type, chtxt, title, btime, etime, opt ) 
+                       VALUES ( '$sql_type', '$chtxt', '$title', '$begin', '$end', '$opt' )"
+               );
+
+               goto end;
+       }
+       if ( $mode_sub eq 'move' ) {
+               my $mode_sub2  = $q->param( 'mode_sub2' );
+               my $title      = $q->param( 'title' );
+               $title =~ s/#/#/g;
+               $title =~ s/\+/ /g;
+
+               $ENV{'LANG'} = 'ja_JP.UTF-8';
+               if ( $mode_sub2 eq 'predict' ) {
+                       eval '$HTML .= `python26 ' . $cfg->param( 'path.rec10' ) . "classify.py -s '$title'`";
+               }
+               elsif ( $mode_sub2 eq 'exec' ) {
+                       eval '$HTML .= `python26 ' . $cfg->param( 'path.rec10' ) . "classify.py -e '$title'`";
+               }
+
+               goto end;
+       }
+
 }
 
 if ( $mode eq 'confirm' ) {
-       # && $display && $start && $stop
+       if ( $mode_sub eq 'reserve' ) {
+               $HTML =~ s/%HTML_TITLE_OPT%/ - Reserver/;
+               $HTML .= qq {<div style="float: left">\n};
+               &parse_program();
 
-       $HTML =~ s/%HTML_TITLE_OPT%/ - Reserver/;
-       $HTML .= qq {<div style="float: left">\n};
-       &parse_program();
+               my $duration = ( str2datetime( $end ) - str2datetime( $begin ) )->delta_minutes;
+               $HTML .= "番組名:$title<br>\nチャンネル:$chname<br>\n放送継続時間:$duration分<br>\n番組内容:$desc<br>\n";
+               if ( $longdesc ) {
+                       $longdesc =~ s/\\n/<br>\n/gs;
+                       $HTML .= "番組内容(長):$longdesc<br>\n";
+               }
+               my $error = &check_error();
+               if ( $error )
+               {
+                       # エラー
 
-       my $duration = ( str2datetime( $end ) - str2datetime( $begin ) )->delta_minutes;
-       $HTML .= "番組名:$title<br>\nチャンネル:$display<br>\n放送継続時間:$duration分<br>\n";
-       if ( &check_error() )
-       {
-               # エラー
+                       $ary_ref = $dbh->selectall_arrayref(
+                               "SELECT start, stop FROM epg_timeline WHERE channel = '$ontv' AND title = '$title' "
+                       );
+                       if ( $error != 1 ) {
+                               $HTML .= "同一の番組の他の放送予定です。<br>\n";
+                               foreach my $line ( @{$ary_ref} ) {
+                                       $begin = $line->[0];
+                                       $end   = $line->[1];
+                                       $begin =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
+                                       $end   =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
+                                       $overlap = &get_overlap() >= 2 ? '不可能' : 
+                                               qq {<a href="rectool.pl?mode=confirm&amp;mode_sub=reserve&amp;chname=$chname&amp;start=$line->[0]&amp;stop=$line->[1]">可能</a>};
+                                       $HTML .= "開始:$begin\n終了:$end\n録画は$overlap<br>\n";
+                               }
+                       }
+               }
+               else {
+                       if ( $chtxt  =~ /\Qbs-nhk-hi\E/ ) {
+                               $selected_f = 'selected';
+                       }
+                       elsif ( $chtxt  =~ /movieplus/ ) {
+                               $selected_h = 'selected';
+                       }
+                       elsif ( $chtxt =~ /bs-nhk/ || $bctype =~ /cs/ ) {
+                               $selected_l = 'selected';
+                       }
+                       elsif ( $bctype =~ /bs|te/ ) {
+                               $selected_g = 'selected';
+                       }
+                       $checked_a  = $chtxt  =~ /animax|atx|disney|kids/ || $category =~ /アニメ/ ? 'checked' : '';
+                       $checked_d  = $title  =~ /\Q[二]\E|[二]|\Q(二)\E|(二)/ ? 'checked' : '';
+                       $checked_5  = $title  =~ /5\.1|5.1/ ? 'checked' : '';
+                       $checked_2  = 'checked';
+
+                       $HTML .= "録画予約の詳細設定を行ってください。<br>\n";
+                       $HTML .= qq {<form method="get" action="rectool.pl">\n};
+                       $HTML .= qq {<input type="hidden" name="mode"   value="reserve">\n};
+                       $HTML .= qq {<input type="hidden" name="chname" value="$chname">\n};
+                       $HTML .= qq {<input type="hidden" name="start"  value="$start">\n};
+                       $HTML .= qq {<input type="hidden" name="stop"   value="$stop">\n};
+                       $HTML .= qq {<select name="opt">\n};
+                       $HTML .= qq {<option value="L" $selected_l>L ***x*** 1250kbps</option>\n};
+                       $HTML .= qq {<option value="G" $selected_g>G 1280x720 2500kbps</option>\n};
+                       $HTML .= qq {<option value="H" $selected_h>H 1280x720 3750kbps</option>\n};
+                       $HTML .= qq {<option value="F" $selected_f>F 1920x1080 5000kbps</option>\n};
+                       $HTML .= qq {<option value="S">S 720x480 1250kbps</option>\n};
+                       $HTML .= qq {</select>\n};
+                       $HTML .= qq {<input type="checkbox" name="opt" value="a" $checked_a>アニメ\n};
+                       $HTML .= qq {<input type="checkbox" name="opt" value="d" $checked_d>二ヶ国語放送\n};
+                       $HTML .= qq {<input type="checkbox" name="opt" value="2" $checked_2>2passモード\n};
+                       $HTML .= qq {<input type="checkbox" name="opt" value="5" $checked_5>5.1ch放送\n};
+                       $HTML .= qq {<br>\n};
+                       $HTML .= qq {<select name="opt">\n};
+                       $HTML .= qq {<option value="">移動なし</option>\n};
+                       $HTML .= qq {<option value="R">録画後移動</option>\n};
+                       $HTML .= qq {<option value="D">解読後移動</option>\n};
+                       $HTML .= qq {<option value="E">縁故後移動</option>\n};
+                       $HTML .= qq {</select>\n};
+                       $HTML .= qq {<input type="checkbox" name="opt" value="N">ファイル名日時追加\n};
+                       $HTML .= qq {<input type="submit" value="予約">\n</form>\n};
+               }
+               goto end;
+       }
+       # End of $mode_sub eq 'reserve';
+
+       if ( $mode_sub eq 'proc' ) {
+               my $type  = $q->param( 'type' );
+               my $title = $q->param( 'title' );
 
+               $HTML .= "詳細設定を行ってください。<br>\n";
+               $HTML .= "タイトル:$title\n<br>\n";
+
+               $HTML .= qq {<form method="get" action="rectool.pl">\n};
+               $HTML .= qq {<input type="hidden" name="mode"     value="change">\n};
+               $HTML .= qq {<input type="hidden" name="mode_sub" value="proc">\n};
+               $HTML .= qq {<input type="hidden" name="type"     value="$type">\n};
+               $HTML .= qq {<input type="hidden" name="title"    value="$title">\n};
+               $HTML .= qq {<select name="chtxt">\n};
                $ary_ref = $dbh->selectall_arrayref(
-                       "SELECT start, stop FROM tv WHERE channel = '$channel' AND title = '$title' "
+                       "SELECT chname, chtxt FROM epg_ch"
                );
-               $HTML .= "同一の番組の他の放送予定です。<br>\n";
                foreach my $line ( @{$ary_ref} ) {
-                       $begin = $line->[0];
-                       $end   = $line->[1];
-                       $begin =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
-                       $end   =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
-                       $overlap = &get_overlap() >= 2 ? '不可能' : 
-                               qq {<a href="rectool.pl?mode=confirm&amp;ch=$display} . 
-                               qq {&amp;start=$line->[0]&amp;stop=$line->[1]">可能</a>};
-                       $HTML .= "開始:$begin\n終了:$end\n録画は$overlap<br>\n";
+                       if ( $line->[1] eq $chtxt ) {
+                               $HTML .= qq {<option value="$line->[1]" selected>$line->[0]</option>\n};
+                       }
+                       else {
+                               $HTML .= qq {<option value="$line->[1]">$line->[0]</option>\n};
+                       }
                }
-       }
-       else {
-               $desc = $dbh->selectrow_array(
-                       "SELECT exp FROM tv WHERE channel = '$channel' AND start = '$start' AND stop = '$stop' "
-               );
-               $selected_hd   = $chtxt =~ /movieplus/ ? 'selected' : '';
-               $selected_full = $chtxt =~ /\Qbs-nhk-hi\E/ ? 'selected' : '';
-               $checked_anime = $chtxt =~ /animax|atx|disney|kids/ ? 'checked' : '';
-               $checked_dual  = $title =~ /\Q[二]\E|[二]|\Q(二)\E|(二)/ ? 'checked' : '';
-               $checked_5_1   = $title =~ /5\.1|5.1/ ? 'checked' : '';
+               $HTML .= qq {</select>\n};
 
-               $HTML .= "番組内容:$desc<br>\n<br>\n録画予約の詳細設定を行ってください。<br>\n";
-               $HTML .= qq {<form method="get" action="rectool.pl">\n};
-               $HTML .= qq {<input type="hidden" name="mode"  value="reserve">\n};
-               $HTML .= qq {<input type="hidden" name="ch"    value="$display">\n};
-               $HTML .= qq {<input type="hidden" name="start" value="$start">\n};
-               $HTML .= qq {<input type="hidden" name="stop"  value="$stop">\n};
                $HTML .= qq {<select name="opt">\n};
-               # $HTML .= qq {<option value="T">TE HD画質(1440x1080)</option>\n};
-               # $HTML .= qq {<option value="F" $check>FULLHD画質(1920x1080)</option>\n};
-               # $HTML .= qq {<option value="Q">WQVGA画質(400x240)</option>\n};
-               $HTML .= qq {<option value="L">L ***x*** 1250kbps</option>\n};
-               $HTML .= qq {<option value="G">G 1280x720 2500kbps</option>\n};
-               $HTML .= qq {<option value="H" $selected_hd>H 1280x720 3750kbps</option>\n};
-               $HTML .= qq {<option value="F" $selected_full>F 1920x1080 5000kbps</option>\n};
+               $HTML .= qq {<option value="L" $selected_l>L ***x*** 1250kbps</option>\n};
+               $HTML .= qq {<option value="G" $selected_g>G 1280x720 2500kbps</option>\n};
+               $HTML .= qq {<option value="H" $selected_h>H 1280x720 3750kbps</option>\n};
+               $HTML .= qq {<option value="F" $selected_f>F 1920x1080 5000kbps</option>\n};
                $HTML .= qq {<option value="S">S 720x480 1250kbps</option>\n};
                $HTML .= qq {</select>\n};
-               $HTML .= qq {<input type="checkbox" name="opt" value="a" $checked_anime>アニメ\n};
-               $HTML .= qq {<input type="checkbox" name="opt" value="d" $checked_dual>二ヶ国語放送\n};
-               $HTML .= qq {<input type="checkbox" name="opt" value="2" checked>2passモード\n};
-               $HTML .= qq {<input type="checkbox" name="opt" value="5" $checked_5_1>5.1ch放送\n};
-               $HTML .= qq {<input type="checkbox" name="opt" value="x">Xvidモード\n};
+               $HTML .= qq {<input type="checkbox" name="opt" value="a" $checked_a>アニメ\n};
+               $HTML .= qq {<input type="checkbox" name="opt" value="d" $checked_d>二ヶ国語放送\n};
+               $HTML .= qq {<input type="checkbox" name="opt" value="2" $checked_2>2passモード\n};
+               $HTML .= qq {<input type="checkbox" name="opt" value="5" $checked_5>5.1ch放送\n};
                $HTML .= qq {<input type="submit" value="予約">\n</form>\n};
+               goto end;
        }
-       goto end;
 }
 
 if ( $mode eq 'reserve' ) {
@@ -752,8 +816,8 @@ if ( $mode eq 'reserve' ) {
        $opt = join '', @opt;
        if ( !&check_error ) {
                $dbh->do( 
-                       "INSERT INTO rectime ( type, chtxt, title, btime, etime, opt ) 
-                       VALUES ( 'res', '$chtxt', '$title', '$begin', '$end', '$opt' )" 
+                       "INSERT INTO timeline ( type, chtxt, title, btime, etime, opt ) 
+                       VALUES ( 'reserve_flexible', '$chtxt', '$title', '$begin', '$end', '$opt' )" 
                );
        }
        $HTML .= "録画予約を実行しました。<br>\n5秒後にトップへ移動します。<br>\n";
@@ -767,16 +831,13 @@ if ( $mode eq 'program' ) {
        $HTML =~ s/%HTML_TITLE_OPT%/ - Program Viewer/;
        $unix = DateTime->now( time_zone => $tz )->strftime( '%Y%m%d%H%M%S' );
        $sql = 
-               "SELECT tv.channel, 
-                       (SELECT display FROM ch WHERE ch.channel = tv.channel), 
-               start, stop, title, category 
-               FROM tv 
-               INNER JOIN chdata ON tv.channel = chdata.ontv 
+               "SELECT channel, chname, start, stop, title, category 
+               FROM epg_timeline 
+               INNER JOIN epg_ch ON epg_timeline.channel = epg_ch.ontv 
                WHERE $unix <= stop %CH% %DATE% %CATEGORY% %KEY% ORDER BY start";
-#              INNER JOIN ch     ON tv.channel = ch.channel
 
-       if ( $channel ) {
-               my $ch = "AND tv.channel = '$channel'";
+       if ( $ontv ) {
+               my $ch = "AND channel = '$ontv'";
                $sql =~ s/%CH%/$ch/;
        }
        if ( $date_sel ) {
@@ -787,8 +848,8 @@ if ( $mode eq 'program' ) {
        }
        if ( $category_sel ) {
                # 一時的
-                       $category_tmp = $category{$category_sel} . $category_sel;
-               my $category = "AND category = '$category_tmp'";
+               #       $category_tmp = $category{$category_sel} . $category_sel;
+               my $category = "AND category = '$category{$category_sel}'";
                $sql =~ s/%CATEGORY%/$category/;
        }
        if ( $key ) {
@@ -808,7 +869,6 @@ if ( $mode eq 'program' ) {
                if ( $date != $prev ) {
                        my $date = DateTime->new(
                                year => $date[0], month  => $date[1], day    => $date[2], 
-#                              hour => $date[3], minute => $date[4], second => $date[5], 
                                locale => 'ja_JP'
                        );
 
@@ -816,10 +876,10 @@ if ( $mode eq 'program' ) {
                        utf8::encode( $dn );
                        $HTML .= qq {--------$date[1]/$date[2]($dn)--------<br>\n};
                }
-               $prg->[1] = $q->url_encode( $prg->[1] );
+               $prg->[5] = $q->url_encode( $prg->[1] );
                $HTML .= qq {$date[1]/$date[2] $date[3]:$date[4] };
-               $HTML .= qq {<a href="rectool.pl?mode=confirm&amp;ch=$prg->[1]};
-               $HTML .= qq {&amp;start=$prg->[2]&amp;stop=$prg->[3]">$prg->[4]</a><br>\n};
+               $HTML .= qq {$prg->[1] } if ( !$ontv );
+               $HTML .= qq {<a href="rectool.pl?mode=confirm&amp;mode_sub=reserve&amp;chname=$prg->[5]&amp;start=$prg->[2]&amp;stop=$prg->[3]">$prg->[4]</a><br>\n};
                $prev = $date;
        }
 
@@ -830,22 +890,22 @@ if ( $mode eq 'list' ) {
 
        $HTML =~ s/%HTML_TITLE_OPT%/ - List/;
 
-       my $type = $q->param( 'type' );
+       my $mode_sub  = $q->param( 'mode_sub' );
        my $recording = $cfg->param( 'path.recpath' );
        my $recorded  = $cfg->param( 'path.recorded' );
 
-       if ( !$type ) {
-               $HTML .= qq {<a href="rectool.pl?mode=list&amp;type=new">録画中のみ</a>\n};
-               $HTML .= qq {<a href="rectool.pl?mode=list&amp;type=old">録画後のみ</a>\n<br>\n};
+       if ( !$mode_sub ) {
+               $HTML .= qq {<a href="rectool.pl?mode=list&amp;mode_sub=new">録画中のみ</a>\n};
+               $HTML .= qq {<a href="rectool.pl?mode=list&amp;mode_sub=old">録画後のみ</a>\n<br>\n};
        }
-       if ( !$type || $type eq 'new' ) {
+       if ( !$mode_sub || $mode_sub eq 'new' ) {
                $HTML .= "録画中のファイル一覧<br>\n";
                &list( $recording );
        }
-       if ( !$type ) {
+       if ( !$mode_sub ) {
                $HTML .= "<br>\n";
        }
-       if ( !$type || $type eq 'old' ) {
+       if ( !$mode_sub || $mode_sub eq 'old' ) {
                $HTML .= "録画後のファイル一覧<br>\n";
                &simple_list( $recorded );
        }
@@ -853,19 +913,20 @@ if ( $mode eq 'list' ) {
        sub list {
                local $path = shift;
                local %list = ();
-               my @exp = ( 'log', 'ts.b25', 'ts.tsmix', 'ts', 'ts.log', 
-                       'sa.avi', 'sa.avi.log', 'm2v', 'wav', 'avi', 'mkv' );
+               my @exp = ( 'log', 'ts.b25', 'ts.tsmix', 'ts', 'ts.log.mbtree', 'ts.log', 
+                       'sa.avi', 'sa.avi.log', 'm2v', 'wav', 'avi', 'mkv', 'mp4' );
                for ( 0..$#exp ) {
                        $exp{$exp[$_]} = $_;
                }
                my $exp_count = scalar keys %exp;
 
-               File::Find::find( \&wanted, $path );
+               my %opt = ( follow => 1, wanted => \&wanted,  );
+               File::Find::find( \%opt, $path );
 
                foreach my $name ( sort { $exp{$a} <=> $exp{$b} } keys %exp ) {
                        $HTML .= $exp{$name} + 1 . " = $name / ";
                }
-               $HTML .= $exp_count+1 . qq { = サムネイル<br>\n○ = 完了 / ● = 書き込み中<br>\n};
+               $HTML .= $exp_count+1 . qq { = サムネイル<br>\n○ = 完了 / ● = 書き込み中 / ◆ = ファイルサイズ異常<br>\n};
                $HTML .= qq {<table summary="listtable" border=1 cellspacing=0>\n<tr>\n};
                $HTML .= qq {<th>タイトル</th>\n};
                $HTML .= qq {<th>$_</th>\n} for ( 1..$exp_count + 1 );
@@ -882,19 +943,18 @@ if ( $mode eq 'list' ) {
                        }
                        foreach ( @flag ) {
                                my $size = $_->{size};
-                               my $last = $_->{last} || '○';
+                               my $last = $_->{last} || ( $_->{size} eq '0 B' ? '◆' : '○' );
                                my $check = $size ? qq {<span title="$size">$last</span>} : '<br>';
                                $HTML .= qq {<td>$check</td>\n};
                        }
-                       if ( $flag[$exp{mkv}] ) {
+                       if ( $flag[$exp{mp4}] ) {
                                s/#/#/g;
                                s/ /\+/g;
-                               my $img = $value->{mkv}->{img};
+                               my $img = $value->{mp4}->{img};
                                $HTML  .= qq {<td><a href="rectool.pl?mode=thumb&amp;title=$img">■</a></td>\n};
-                               my $pre = qq {<a href="rectool.pl?mode=move&amp;type=predict&amp;title=$_">予測</a>};
+                               my $pre = qq {<a href="rectool.pl?mode=change&amp;mode_sub=move&amp;mode_sub2=predict&amp;title=$_">予測</a>};
                                $HTML  .= qq {<td>$pre</td>\n};
-#                              my $exe = qq {<a href="rectool.pl?mode=move&amp;type=exec&amp;title=$_">実行</a>};
-                               my $exe = qq {実行};
+                               my $exe = qq {<a href="rectool.pl?mode=change&amp;mode_sub=move&amp;mode_sub2=exec&amp;title=$_">実行</a>};
                                $HTML  .= qq {<td>$exe</td>\n};
                        }
                        else {
@@ -915,18 +975,26 @@ if ( $mode eq 'list' ) {
                        my ( $size, $last ) = &get_size( $File::Find::name );
                        my $img;
                        $File::Find::name =~ s/\.temp$//;
-                       if ( $title !~ /[^0-9A-F]/ ) {
-                               $title = pack( 'H*', $title );
-                               $title = 'Base16_'.$title;
+                       if ( !$title ) {
+                               $title = '_error_exp_'.$_;
+                               $exp   = 'log';
+                       }
+                       if ( $title !~ /[^0-9A-F]+/ ) {
+                               my $tmp = pack( 'H*', $title );
+                               if ( !$tmp ) {
+                                       $title = '_error_b16_'.$_;
+                                       $exp   = 'log';
+                               }
+                               else {
+                                       $title = 'Base16_'.$tmp;
+                               }
                        }
-                       if ( $_ =~ /mkv/ ) {
+                       if ( $_ =~ /mp4/ ) {
                                my $tmp = $title;
                                $tmp =~ s/#/#/g;
                                $tmp =~ s/ /\+/g;
                                $img = $tmp;
-#                              $img = qq {<img width=160 height=120 src="rectool.pl?mode=thumb&amp;title=$tmp"><br>\n};
                        }
-                       die $_ if ( !$title );
                        $list{$title}->{$exp} = { 'last' => $last, 'size' => $size, 'img' => $img };
                }
        }
@@ -975,20 +1043,6 @@ if ( $mode eq 'list' ) {
        }
 }
 
-if ( $mode eq 'move' ) {
-       my $type  = $q->param( 'type' );
-       my $title = $q->param( 'title' );
-       $title =~ s/#/#/g;
-       $title =~ s/\+/ /g;
-
-       if ( $type eq 'predict' ) {
-               eval '$HTML .= `python26 ' . $cfg->param( 'path.rec10' ) . "classify.py -s '$title'`";
-       }
-       elsif ( $type eq 'exec' ) {
-               eval '$HTML .= `python26 ' . $cfg->param( 'path.rec10' ) . "classify.py -e '$title'`";
-       }
-}
-
 if ( $mode eq 'thumb' ) {
        my $title = $q->param( 'title' );
        my $pos  = $q->param( 'pos' );
@@ -997,73 +1051,235 @@ if ( $mode eq 'thumb' ) {
        $title =~ s/#/#/g;
 
        print "Content-Type: image/jpeg\n\n";
-       exec "ffmpeg -ss 300 -i '$recording/$title.mkv' -f image2 -pix_fmt jpg -vframes 1 -s 320x240 -";
+       exec "ffmpeg -ss 300 -i '$recording/$title.mp4' -f image2 -pix_fmt jpg -vframes 1 -s 320x240 -";
        exit;
 }
 
 if ( $mode eq 'check' ) {
 }
 
-if ( $mode eq 'expert' ) {
-       my $ary_ref;
-       my $type = $q->param( 'type' );
-       $HTML =~ s/%HTML_TITLE_OPT%/ - Expert/;
+if ( $mode eq 'bravia' ) {
+       $HTML =~ s/%HTML_TITLE_OPT%/ - Bravia/;
+       $HTML .= qq {<div>\n};
+       $HTML .= qq {<form method="get" action="rectool.pl">\n};
        $HTML .= qq {<div>\n};
+       $HTML .= qq {<table summary="bayestable" border=1 cellspacing=0>\n<tr>\n};
+       $HTML .= qq {<th>ID</th>\n};
+       $HTML .= qq {<th>チャンネル</th>\n};
+       $HTML .= qq {<th>タイトル</th>\n};
+       $HTML .= qq {<th><a href="rectool.pl?mode=bravia">開始時刻</a></th>\n};
+       $HTML .= qq {<th>終了時刻</th>\n};
+       $HTML .= qq {<th>録画時間</th>\n};
+       $HTML .= qq {<th><a href="rectool.pl?mode=bravia&amp;order=point">ポイント</a></th>\n};
+       $HTML .= qq {<th>予約</th>\n};
+       $HTML .= qq {</tr>\n};
 
-       if ( $type eq 'reget' ) {
-               my $display = $q->param( 'ch' );
-               my $SQL_WHERE;
-               if ( $display =~ /^bs$|^cs.$/ ) {
-                       $SQL_WHERE = "chdata.bctype = '$display'";
+       my $order = $q->param( 'order' );
+       if ( $order ne 'point' ) {
+               $order = 'btime';
+       }
+       else {
+               $order = 'point DESC';
+       }
+       my $ary_ref = $dbh->selectall_arrayref(
+               "SELECT id, chtxt, title, btime, etime, point 
+               FROM auto_timeline_bayes 
+               ORDER BY $order" );
+
+       foreach my $line ( @{ $ary_ref } ) {
+               my ( $begin, $end, $diff ) = &str2readable( $line->[3], $line->[4] );
+
+               $HTML .= qq {<tr align="center">\n};
+               $HTML .= qq {<td>$line->[0]</td>\n};
+               $HTML .= qq {<td>$line->[1]</td>\n};
+               $HTML .= qq {<td>$line->[2]</td>\n};
+               $HTML .= qq {<td>$begin</td>\n<td>$end</td>\n<td>$diff</td>\n};
+               $HTML .= qq {<td>$line->[5]</td>\n};
+               $HTML .= qq {<td><a href="rectool.pl?mode=confirm&amp;mode_sub=reserve&amp;bayesid=$line->[0]">予約</a></td>\n};
+               $HTML .= qq {</tr>\n};
+       }
+       $HTML .= qq {</table>\n};
+       $HTML .= qq {</div>\n};
+       $HTML .= qq {</form>\n};
+
+}
+
+if ( $mode eq 'proc' ) {
+       $HTML =~ s/%HTML_TITLE_OPT%/ - Proposal/;
+       $HTML .= qq {<div>\n};
+       $HTML .= qq {<table summary="proctable" border=1 cellspacing=0>\n<tr>\n};
+       $HTML .= qq {<th>タイプ</th>\n};
+       $HTML .= qq {<th>タイトル</th>\n};
+       $HTML .= qq {<th>予約</th>\n};
+       $HTML .= qq {</tr>\n};
+
+       my $ary_ref = $dbh->selectall_arrayref(
+               "SELECT type, title 
+               FROM auto_proc " );
+
+       foreach my $line ( @{ $ary_ref } ) {
+               my $url;
+               $line->[2] = $q->url_encode( $line->[1] );
+
+               if ( $line->[0] =~ /^auto_suggest_(dec|enc)/ ) {
+                       $url = qq {rectool.pl?mode=confirm&amp;mode_sub=proc&amp;type=$line->[0]&amp;title=$line->[2]};
                }
                else {
-                       $SQL_WHERE = "display = '$display'";
+                       $url = qq {rectool.pl?mode=change&amp;mode_sub=proc&amp;type=$line->[0]&amp;title=$line->[2]};
                }
-               my $ontv = $dbh->selectrow_array( 
-                       "SELECT ontv FROM ch 
-                       INNER JOIN chdata ON ch.channel = chdata.ontv 
-                       WHERE $SQL_WHERE " );
-               $dbh->do( "UPDATE chdata SET status = '2' WHERE ontv = '$ontv' " );
+               $HTML .= qq {<tr align="center">\n};
+               $HTML .= qq {<td>$type{$line->[0]}</td>\n};
+               $HTML .= qq {<td>$line->[1]</td>\n};
+               $HTML .= qq {<td><a href="$url">予約</a></td>\n};
+               $HTML .= qq {</tr>\n};
+       }
+
+       $HTML .= qq {</table>\n};
+}
+
+if ( $mode eq 'jbk' ) {
+       $HTML =~ s/%HTML_TITLE_OPT%/ - JBK/;
+       $HTML .= qq {<div>\n};
+
+       if ( $mode_sub eq 'add' ) {
+               my $keyword = $q->param( 'keyword' );
+               $HTML .= "キーワード「$keyword」を追加しました。<br>\n";
+               $dbh->do( 
+                       "INSERT INTO in_auto_jbk_key ( keyword ) 
+                       VALUES ( '$keyword' )" 
+               );
+       }
+       elsif ( $mode_sub eq 'del' ) {
+               my $id = $q->param( 'id' );
+               my $keyword = $dbh->selectrow_array( 
+                       "SELECT keyword FROM in_auto_jbk_key 
+                       WHERE id = '$id' " );
+               $HTML .= "キーワード「$keyword」を削除しました。<br>\n";
+               $dbh->do( 
+                       "DELETE FROM in_auto_jbk_key WHERE id = '$id'" 
+               );
+       }
+
+       $HTML .= qq {<table summary="jbktable" border=1 cellspacing=0>\n<tr>\n};
+       $HTML .= qq {<th>ID</th>\n};
+       $HTML .= qq {<th>キーワード</th>\n};
+       $HTML .= qq {<th>削除</th>\n};
+       $HTML .= qq {</tr>\n};
+
+       my $ary_ref = $dbh->selectall_arrayref(
+               "SELECT id, keyword 
+               FROM in_auto_jbk_key
+               ORDER BY id " );
+
+       foreach my $line ( @{ $ary_ref } ) {
+               my $url = "rectool.pl?mode=jbk&amp;mode_sub=del&amp;id=$line->[0]";
+
+               $HTML .= qq {<tr align="center">\n};
+               $HTML .= qq {<td>$line->[0]</td>\n};
+               $HTML .= qq {<td>$line->[1]</td>\n};
+               $HTML .= qq {<td><a href="$url">削除</a></td>\n};
+               $HTML .= qq {</tr>\n};
+       }
+
+       $HTML .= qq {</table>\n};
+
+       $HTML .= qq {<form method="get" action="rectool.pl">\n};
+       $HTML .= qq {<div>\n};
+       $HTML .= qq {<input type="hidden" name="mode" value="jbk">\n};
+       $HTML .= qq {<input type="hidden" name="mode_sub" value="add">\n};
+       $HTML .= qq {<input name="keyword" type="text">\n};
+       $HTML .= qq {<input type="submit" value="追加">\n</div>\n</form>\n<br>\n};
+
+       $HTML .= qq {<table summary="jbkrestable" border=1 cellspacing=0>\n<tr>\n};
+       $HTML .= qq {<th>ID</th>\n};
+       $HTML .= qq {<th>チャンネル</th>\n};
+       $HTML .= qq {<th>タイトル</th>\n};
+       $HTML .= qq {<th>開始時刻</th>\n};
+       $HTML .= qq {<th>終了時刻</th>\n};
+       $HTML .= qq {<th>録画時間</th>\n};
+       $HTML .= qq {<th>予約</th>\n};
+       $HTML .= qq {</tr>\n};
+
+       my $ary_ref = $dbh->selectall_arrayref(
+               "SELECT id, chtxt, title, btime, etime 
+               FROM auto_timeline_keyword " );
+
+       foreach my $line ( @{ $ary_ref } ) {
+               my ( $begin, $end, $diff ) = &str2readable( $line->[3], $line->[4] );
+               $line->[3] =~ s/(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/$1$2$3$4$5$6/;
+               $line->[4] =~ s/(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/$1$2$3$4$5$6/;
+               my $url = qq "rectool.pl?mode=confirm&amp;mode_sub=reserve&amp;chtxt=$line->[1]&amp;start=$line->[3]&amp;stop=$line->[4]";
+
+               $HTML .= qq {<tr align="center">\n};
+               $HTML .= qq {<td>$line->[0]</td>\n};
+               $HTML .= qq {<td>$line->[1]</td>\n};
+               $HTML .= qq {<td>$line->[2]</td>\n};
+               $HTML .= qq {<td>$begin</td>\n};
+               $HTML .= qq {<td>$end</td>\n};
+               $HTML .= qq {<td>$diff</td>\n};
+               $HTML .= qq {<td><a href="$url">予約</a></td>\n};
+               $HTML .= qq {</tr>\n};
+       }
+
+       $HTML .= qq {</table>\n};
+
+}
+
+if ( $mode eq 'expert' ) {
+       my $ary_ref;
+       my $mode_sub = $q->param( 'mode_sub' );
+       $HTML =~ s/%HTML_TITLE_OPT%/ - Expert/;
+       $HTML .= qq {<div>\n};
+
+       if ( $mode_sub eq 'reget' ) {
+               my $bctype = $q->param( 'bctype' );
+               my ( $ontv, $chname ) = $dbh->selectrow_array( 
+                       "SELECT ontv, chname FROM epg_ch 
+                       WHERE bctype = '$bctype' " );
+               $HTML .= "Update for $chname ( ontv: $ontv ) has been reserved.<br>\n";
+               $dbh->do( "UPDATE epg_ch SET status = '2' WHERE ontv = '$ontv' " );
                goto end;
        }
 
 
        $ary_ref = $dbh->selectcol_arrayref(
-               "SELECT DISTINCT category FROM tv"
+               "SELECT DISTINCT category FROM epg_timeline"
        );
        # 一時的
-               my @category = map { $category{$_} . $_ } sort keys %category;
-       # my @category = sort keys %category;
+       #       my @category = map { $category{$_} . $_ } sort keys %category;
+       my @category = sort values %category;
        $HTML .= qq {<hr>\n番組表のカテゴリ一覧と内蔵の一覧の合致を確認中...\n};
-       # $HTML .= qq {番組表:@{$ary_ref}<br>\n内蔵:@category<br>\n};
        if ( List::Compare->new( $ary_ref, \@category )->get_symdiff ) {
                $HTML .= qq {一致しません<br>\n};
+               $HTML .= qq {番組表:@{$ary_ref}<br>\n内蔵:@category<br>\n};
        }
        else {
                $HTML .= qq {一致しました<br>\n};
        }
 
-       my @ary = $dbh->selectrow_array( "SELECT terec, bscsrec, b252ts, ts2avi FROM status" );
+       my @ary = $dbh->selectrow_array( "SELECT terec, bscsrec, b252ts, ts2avi FROM in_status" );
        $HTML .= qq {<hr>\n地上波録画数:$ary[0]\n衛星波録画数:$ary[1]\n解読数:$ary[2]\n縁故数:$ary[3]\n<br>\n};
 
        use List::Compare;
-       $ary_ref = $dbh->selectall_arrayref( "SELECT display, channel FROM ch INNER JOIN chdata ON ch.channel = chdata.ontv" );
+       $ary_ref = $dbh->selectall_arrayref( "SELECT chname, chtxt FROM epg_ch" );
        my $prev;
        $HTML .= "<hr>\n番組表の欠落<br>\n";
        foreach my $line ( @{$ary_ref} ) {
-               my $ary_ref = $dbh->selectall_arrayref( "SELECT start, stop, title FROM tv WHERE channel = '$line->[1]' ORDER BY start" );
+               my $ary_ref = $dbh->selectall_arrayref( 
+                       "SELECT start, stop, title FROM epg_timeline WHERE channel = '$line->[1]' ORDER BY start" 
+               );
                my $error;
                my @program_old = ( '', $ary_ref->[0]->[0] );
                my $program_old = \@program_old;
 
                foreach my $program_new ( @{$ary_ref} ) {
                        if ( $program_old->[1] ne $program_new->[0] && 
-                               $program_old->[2] !~ /クロジング|クロージング|エンディング|休止|ミッドナイトプレゼント/ && 
+                               $program_old->[2] !~ /クロ?ジング|クロージング|エンディング|休止|ミッドナイトプレゼント/ && 
                                $program_new->[2] !~ /オープニング|ウィークリー・インフォメーション|モーニングプレゼント/ && 
-                               ( str2datetime( $program_new->[0], 1 ) - str2datetime( $program_old->[1], 1 ) )->delta_minutes > 30 ) {
+                               ( str2datetime( $program_new->[0] ) - str2datetime( $program_old->[1] ) )->delta_minutes > 30 ) {
                                $program_old->[1] =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
                                $program_new->[0] =~ s/(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/$1-$2-$3 $4:$5:$6/;
-                               $error .= qq{    $program_old->[2]    $program_old->[1]\n      $program_new->[2]    $program_new->[0]\n};
+                               $error .= qq{    $program_old->[2]    $program_old->[1]\n    ?  $program_new->[2]    $program_new->[0]\n};
                        }
                        $program_old = $program_new;
                }
@@ -1071,8 +1287,8 @@ if ( $mode eq 'expert' ) {
                }
 
        $ary_ref = $dbh->selectall_arrayref( 
-               "SELECT display, chtxt, ontv, chdata.bctype, ch, csch, updatetime, status FROM chdata 
-               INNER JOIN ch ON ch.channel = chdata.ontv 
+               "SELECT chname, chtxt, ontv, bctype, ch, csch, updatetime, status 
+               FROM epg_ch 
                ORDER BY bctype " );
        $HTML .= qq {<hr>\n番組表の更新状況<br>\n};
        $HTML .= qq {<table summary="channeltable" border=1 cellspacing=0>\n<tr>\n};
@@ -1097,13 +1313,14 @@ if ( $mode eq 'expert' ) {
        $HTML .= qq {<div>\n};
        $HTML .= qq {番組表を再取得する\n};
        $HTML .= qq {<input type="hidden" name="mode" value="expert">\n};
-       $HTML .= qq {<input type="hidden" name="type" value="reget">\n};
-       $HTML .= qq {<select name="ch">\n};
-       $ary_ref = $dbh->selectcol_arrayref(
-               "SELECT display FROM ch INNER JOIN chdata ON ch.channel = chdata.ontv WHERE chdata.bctype NOT LIKE '_s%' "
+       $HTML .= qq {<input type="hidden" name="mode_sub" value="reget">\n};
+       $HTML .= qq {<select name="bctype">\n};
+       $ary_ref = $dbh->selectall_arrayref(
+               "SELECT chname, bctype 
+               FROM epg_ch WHERE bctype NOT LIKE '_s%' "
        );
-       foreach my $ch ( @{$ary_ref} ) {
-               $HTML .= qq {<option value="$ch">$ch</option>\n};
+       foreach my $line ( @{$ary_ref} ) {
+               $HTML .= qq {<option value="$line->[1]">$line->[0]</option>\n};
        }
        $HTML .= qq {<option value="bs">BS</option>\n};
        $HTML .= qq {<option value="cs1">CS1</option>\n};
@@ -1114,8 +1331,8 @@ if ( $mode eq 'expert' ) {
 
 
        $ary_ref = $dbh->selectall_arrayref(
-               "SELECT id, type, rectime.chtxt, title, btime, etime, deltaday, deltatime 
-               FROM rectim
+               "SELECT id, type, chtxt, title, btime, etime, deltaday, deltatime 
+               FROM timelin
                ORDER BY id ");
        $HTML .= qq {<hr>\n予約表<br>\n};
        $HTML .= qq {<table summary="rectimetable" border=1 cellspacing=0>\n<tr>\n};
@@ -1175,34 +1392,6 @@ $HTML .= <<EOM;
 EOM
 
 #<div align="center">
-$HTML_ADV_TEXT = <<EOM;
-<script type="text/javascript"><!--
-google_ad_client = "pub-6837289609486635";
-/* 728x90, 作成済み 09/07/20 */
-google_ad_slot = "6679390404";
-google_ad_width = 728;
-google_ad_height = 90;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script>
-EOM
-
-$HTML_ADV_IMG = <<EOM;
-<script type="text/javascript"><!--
-google_ad_client = "pub-6837289609486635";
-/* 728x90, 作成済み 09/07/20 */
-google_ad_slot = "5941705087";
-google_ad_width = 728;
-google_ad_height = 90;
-//-->
-</script>
-<script type="text/javascript"
-src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
-</script>
-EOM
-
 #$HTML_ADV = $HTML_ADV_IMG . $HTML_ADV_TEXT if ( !$HTML_ADV );
 $HTML_HEADER = qq {<div style="text-align: center">\n$HTML_ADV\n</div>\n};
 
@@ -1227,31 +1416,38 @@ sub draw_menu {
        $HTML_HEADER .= qq {<a href="rectool.pl?mode=schedule">予約確認</a>\n};
        $HTML_HEADER .= qq {<a href="rectool.pl?mode=graph">予約状況(画像版)</a>\n};
        $HTML_HEADER .= qq {<a href="rectool.pl?mode=list">録画一覧</a>\n};
-#      $HTML_HEADER .= qq {<a href="rectool.pl?mode=edit">新規予約</a>\n};
+       $HTML_HEADER .= qq {<a href="rectool.pl?mode=bravia">おまかせ</a>\n};
+       $HTML_HEADER .= qq {<a href="rectool.pl?mode=expert">玄人仕様</a>\n};
+       $HTML_HEADER .= qq {<a href="rectool.pl?mode=proc">復旧支援</a>\n};
+       $HTML_HEADER .= qq {<a href="rectool.pl?mode=jbk">地引</a>\n};
        $HTML_HEADER .= qq {<a href="../rec10web/rec10web.py">新規予約</a>\n};
+       $HTML_HEADER .= qq {<a href="rectool.pl?mode=edit">新規予約2</a>\n};
        $HTML_HEADER .= qq {</span>\n};
        $HTML_HEADER .= qq {<hr style="clear: both; background-color: grey; height: 4px">\n};
        $HTML_HEADER .= qq {</div>\n};
 }
 
 sub draw_form {
-       $channel = $dbh->selectrow_array("SELECT channel FROM ch WHERE display = '$display' ");
+       $chname = $q->param( 'chname' );
+       $key    = $q->param( 'key' );
+       $ontv = $dbh->selectrow_array("SELECT ontv FROM epg_ch WHERE chname = '$chname' ");
 
-       # チャンネル指定
        $HTML .= qq {<div style="float: left">\n};
        $HTML .= qq {<form method="get" action="rectool.pl">\n};
        $HTML .= qq {<div>\n};
        $HTML .= qq {<input type="hidden" name="mode" value="program">\n};
-       $HTML .= qq {<select name="ch">\n<option value="" selected>無指定</option>\n};
+
+       # チャンネル指定
+       $HTML .= qq {<select name="chname">\n<option value="" selected>無指定</option>\n};
        $ary_ref = $dbh->selectcol_arrayref(
-               "SELECT display FROM ch INNER JOIN chdata ON ch.channel = chdata.ontv"
+               "SELECT chname FROM epg_ch"
        );
-       foreach my $ch ( @{$ary_ref} ) {
-               if ( $ch eq $display ) {
-                       $HTML .= qq {<option value="$ch" selected>$ch</option>\n};
+       foreach my $line ( @{$ary_ref} ) {
+               if ( $line eq $chname ) {
+                       $HTML .= qq {<option value="$line" selected>$line</option>\n};
                }
                else {
-                       $HTML .= qq {<option value="$ch">$ch</option>\n};
+                       $HTML .= qq {<option value="$line">$line</option>\n};
                }
        }
        $HTML .= qq {</select>\n};
@@ -1259,7 +1455,7 @@ sub draw_form {
        # 日付指定
        $HTML .= qq {<select name="date">\n<option value="" selected>無指定</option>\n};
        $ary_ref = $dbh->selectcol_arrayref(
-               "SELECT DISTINCT $SQL{'SUBSTR'} FROM tv"
+               "SELECT DISTINCT SUBSTRING(start, 1, 8) FROM epg_timeline ORDER BY start"
        );
        $date_sel = $q->param( 'date' );
        foreach my $date ( @{ $ary_ref } ) {
@@ -1296,35 +1492,81 @@ sub draw_form {
 }
 
 sub parse_program {
-       @start   = $start =~ /(.{4})(.{2})(.{2})(.{2})(.{2})/;
-       @stop    = $stop  =~ /(.{4})(.{2})(.{2})(.{2})(.{2})/;
-       $channel = $dbh->selectrow_array("SELECT channel FROM ch  WHERE display = '$display'");
-       $title   = $dbh->selectrow_array("SELECT title   FROM tv  WHERE channel = '$channel' AND start = '$start' AND stop = '$stop' ");
-       $chtxt   = $dbh->selectrow_array("SELECT chtxt   FROM chdata WHERE ontv = '$channel'");
-       $bctype  = $dbh->selectrow_array("SELECT bctype  FROM chdata WHERE ontv = '$channel'");
+       $chname  = $q->param( 'chname' );
+       $chtxt   = $q->param( 'chtxt' );
+       $start   = $q->param( 'start' );
+       $stop    = $q->param( 'stop' );
+       $bayesid = $q->param( 'bayesid' );
+       $id      = $q->param( 'id' );
+
+       if ( $chname ) {
+               $ontv     = $dbh->selectrow_array("SELECT ontv   FROM epg_ch WHERE chname = '$chname'");
+               $chtxt    = $dbh->selectrow_array("SELECT chtxt  FROM epg_ch WHERE ontv   = '$ontv'");
+       }
+       elsif ( $chtxt ) {
+               $ontv     = $dbh->selectrow_array("SELECT ontv   FROM epg_ch WHERE chtxt  = '$chtxt'");
+               $chname   = $dbh->selectrow_array("SELECT chname FROM epg_ch WHERE ontv   = '$ontv'");
+       }
+       $title    = $dbh->selectrow_array("SELECT title    FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' ");
+       $desc     = $dbh->selectrow_array("SELECT exp      FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' ");
+       $longdesc = $dbh->selectrow_array("SELECT longexp  FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' ");
+       $category = $dbh->selectrow_array("SELECT category FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' ");
+       $bctype   = $dbh->selectrow_array("SELECT bctype   FROM epg_ch       WHERE ontv    = '$ontv'");
+
+       if ( $bayesid ) {
+               ( $chtxt, $title, $begin, $end ) = $dbh->selectrow_array( 
+                       "SELECT chtxt, title, btime, etime FROM auto_timeline_bayes WHERE id = '$bayesid' " 
+               );
+               ( $ontv, $chname, $bctype ) = $dbh->selectrow_array( 
+                       "SELECT ontv, chname, bctype FROM epg_ch WHERE chtxt = '$chtxt' " 
+               );
+               $start = str2datetime( $begin )->strftime( '%Y%m%d%H%M%S' );
+               $stop  = str2datetime( $end   )->strftime( '%Y%m%d%H%M%S' );
+               ( $desc, $longdesc, $category ) = $dbh->selectrow_array( 
+                       "SELECT exp, longexp, category FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' " 
+               );
+       }
+       if ( $id ) {
+               ( $type, $chtxt, $title, $begin, $end, $deltaday, $deltatime, $opt ) = $dbh->selectrow_array( 
+                       "SELECT type, chtxt, title, btime, etime, deltaday, deltatime, opt 
+                       FROM timeline WHERE id = '$id' " 
+               );
+               ( $ontv, $chname, $bctype ) = $dbh->selectrow_array( 
+                       "SELECT ontv, chname, bctype FROM epg_ch WHERE chtxt = '$chtxt' " 
+               );
+               $start = str2datetime( $begin )->strftime( '%Y%m%d%H%M%S' );
+               $stop  = str2datetime( $end   )->strftime( '%Y%m%d%H%M%S' );
+               ( $desc, $longdesc, $category ) = $dbh->selectrow_array( 
+                       "SELECT exp, longexp, category FROM epg_timeline WHERE channel = '$ontv' AND start = '$start' AND stop = '$stop' " 
+               );
+       }
        if ( $bctype =~ /.s/ ) {
-               $bctype = '_s%';
+               $bctype_sql = '_s%';
        }
        elsif ( $bctype =~ /te/ ) {
-               $bctype = 'te%';
+               $bctype_sql = 'te%';
        }
+       @start = $start =~ /(.{4})(.{2})(.{2})(.{2})(.{2})/;
+       @stop  = $stop  =~ /(.{4})(.{2})(.{2})(.{2})(.{2})/;
        $begin = sprintf( '%04d-%02d-%02d %02d:%02d:%02d', @start, '00' );
        $end   = sprintf( '%04d-%02d-%02d %02d:%02d:%02d', @stop , '00' );
 }
 
 sub check_error {
-       my $is_error = 1;
+       my $is_error;
+       my $is_same = $dbh->selectrow_array( 
+               "SELECT COUNT(*) FROM timeline WHERE chtxt = '$chtxt' AND btime = '$begin' AND etime = '$end'" 
+       );
        my @overlap = &get_overlap();
 
-       if ( $dbh->selectrow_array( 
-               "SELECT COUNT(*) FROM rectime 
-               WHERE chtxt = '$chtxt' AND btime = '$begin' AND etime = '$end'" 
-       ) ) {
+       if ( $is_same ) {
                $HTML .= "同一の番組が既に存在します。<br>\n";
+               $is_error = 1;
        }
        elsif ( $overlap[0] >= 2 ) {
                $HTML .= "時間が被る番組が既に2個存在します。<br>\n";
                $HTML .= $overlap[1];
+               $is_error = 2;
        }
        else {
                $is_error = 0;
@@ -1337,9 +1579,9 @@ sub get_overlap {
 
        my $ary_ref = $dbh->selectall_arrayref(
                "SELECT btime, etime, title
-               FROM rectim
-               INNER JOIN chdata ON rectime.chtxt = chdata.chtxt 
-               WHERE bctype LIKE '$bctype' AND type IN ( 'rec', 'res', 'key', 'keyevery', 'tsrecording' ) 
+               FROM timelin
+               INNER JOIN epg_ch ON timeline.chtxt = epg_ch.chtxt 
+               WHERE bctype LIKE '$bctype_sql' AND type IN $type_user_made 
                AND btime < '$end' 
                AND etime > '$begin' 
                "
@@ -1349,7 +1591,7 @@ sub get_overlap {
        my $overlap = $max = 0;
        my $str;
        foreach my $prg ( @{ $ary_ref } ) {
-               $str .= "$prg->[0]  $prg->[1] : $prg->[2]<br>\n";
+               $str .= "$prg->[0] ? $prg->[1] : $prg->[2]<br>\n";
                $overlap{$prg->[0]} += 1;
                $overlap{$prg->[1]} -= 1;
        }
@@ -1365,20 +1607,92 @@ sub get_overlap {
        }
 }
 
+sub strisjoined {
+       my $str = shift;
+
+       return $str =~ /.{4}-.{2}-.{2} .{2}:.{2}:.{2}/ ? 0 : 1;
+}
+
 sub str2datetime {
        my $str    = shift;
-       my $joined = shift;
        my @time;
 
-       if ( $joined ) {
+       if ( strisjoined( $str ) ) {
                @time = $str =~ /(.{4})(.{2})(.{2})(.{2})(.{2})(.{2})/;
        }
        else {
                @time = $str =~ /(.{4})-(.{2})-(.{2}) (.{2}):(.{2}):(.{2})/;
        }
        return DateTime->new(
-               year => $time[0], month  => $time[1], day    => $time[2],
-               hour => $time[3], minute => $time[4], second => $time[5], 
+               year   => $time[0], month     => $time[1], day    => $time[2],
+               hour   => $time[3], minute    => $time[4], second => $time[5], 
+               locale => 'ja_JP' , time_zone => $tz
        );
 }
 
+sub str2dayname {
+       my  $str = shift;
+       our %day_name_cache;
+
+       if ( !$day_name_cache{$str} ) {
+               $day_name_cache{$str} = str2datetime( $str )->day_name;
+       }
+       return $day_name_cache{$str};
+}
+
+sub str2readable { 
+       my $begin = shift;
+       my $end   = shift;
+
+       my $dt_begin = &str2datetime( $begin );
+       my $dt_end   = &str2datetime( $end );
+
+       my $str_begin = $dt_begin->strftime( '%m/%d(%a) %H:%M' );
+       my $str_end   = $dt_end  ->strftime( $dt_begin->day == $dt_end->day ? '%H:%M' : '翌 %H:%M' );
+       utf8::encode( $str_begin );
+
+       my ( $sec, $min, $hour );
+       $sec  = $dt_end->epoch - $dt_begin->epoch;
+       $min  = int( $sec / 60 );
+       $sec  = $sec - $min * 60;
+       $hour = int( $min / 60 );
+       $min  = $min - $hour * 60;
+       my $str_diff = '';
+       $str_diff .= $hour . '時間' if ( $hour );
+       $str_diff .= $min  . '分'   if ( $min );
+       $str_diff .= $sec  . '秒'   if ( $sec );
+
+       return ( $str_begin, $str_end, $str_diff );
+}
+
+sub sqlgetsuggested {
+       require Encode;
+       require Text::Ngram;
+
+       my ( $btime, $etime ) = @_;
+
+       $btime_bgn = $btime->clone->subtract( hours => $deltatime )->strftime( '%Y%m%d%H%M%S' );
+       $btime_end = $btime->clone->add(      hours => $deltatime )->strftime( '%Y%m%d%H%M%S' );
+       $etime_bgn = $etime->clone->subtract( hours => $deltatime )->strftime( '%Y%m%d%H%M%S' );
+       $etime_end = $etime->clone->add(      hours => $deltatime )->strftime( '%Y%m%d%H%M%S' );
+
+       my $ontv = $dbh->selectrow_array( "SELECT ontv FROM epg_ch WHERE chtxt = '$chtxt' " );
+       $ary_ref = $dbh->selectall_arrayref(
+               "SELECT start, stop, title, exp 
+               FROM epg_timeline 
+               WHERE channel = '$ontv' 
+               AND start BETWEEN '$btime_bgn' AND '$btime_end' 
+               AND stop  BETWEEN '$etime_bgn' AND '$etime_end' "
+       );
+
+       my %hash;
+       my $hash_r = Text::Ngram::ngram_counts( Encode::decode_utf8( $title ), 2 ); # bi-gram
+       foreach my $program ( @{$ary_ref} ) {
+               my $hash_k = Text::Ngram::ngram_counts( Encode::decode_utf8( $program->[2] ), 2 );
+               my $point;
+               map $point += $hash_k->{$_}, keys %{$hash_r};
+               push @{$hash{$point}}, $program if ( $point );
+       }
+
+       return %hash;
+}