our
$VERSION
=
"1.012"
;
our
$debug
= 0 ;
our
$ct
;
our
$opts_href
;
our
%rec_files
;
our
%iplay_files
;
our
%recorded_files
;
our
$today_mins
;
BEGIN {
$ct
= new Config::Crontab;
$ct
->strict(0) ;
$ct
->
read
;
$ct
->strict(1) ;
$opts_href
= {
'app'
=>
undef
,
'padding'
=> 2,
'early'
=> 30,
'recprog'
=>
''
,
'iplayprog'
=>
''
,
'video_dir'
=>
''
,
'audio_dir'
=>
''
,
'crontag'
=>
'dvb-record'
,
'crontag_iplay'
=>
'iplay-record'
,
'run_dir'
=>
''
,
'run_ext'
=>
'.lst'
,
'video_ext'
=>
'.ts'
,
'audio_ext'
=>
'.mp3'
,
'max_timeslip'
=> 60,
'log_dir'
=>
''
,
} ;
%rec_files
= () ;
%iplay_files
= () ;
%recorded_files
= () ;
my
$today_dt
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::parse_date(
"today"
,
"0:00"
) ;
$today_mins
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2mins(
$today_dt
) ;
}
sub
set
{
my
(
%options
) =
@_
;
foreach
my
$opt
(
keys
%options
)
{
$opts_href
->{
$opt
} =
$options
{
$opt
} ;
}
$debug
=
$options
{
'debug'
}
if
exists
(
$options
{
'debug'
}) ;
foreach
my
$d
(
qw/run_dir video_dir audio_dir/
)
{
$opts_href
->{
$d
} = Linux::DVB::DVBT::Apps::QuartzPVR::Path::expand_path(
$options
{
$d
}) ;
}
foreach
my
$p
(
qw/log_dir recprog iplayprog/
)
{
my
(
$file
,
$dir
,
$suffix
) = fileparse(
$opts_href
->{
$p
},
qr/\.[^.]*/
);
$dir
= Linux::DVB::DVBT::Apps::QuartzPVR::Path::expand_path(
$dir
) ;
$opts_href
->{
$p
} =
"$dir$file$suffix"
;
}
}
sub
get_blocks
{
my
(
$tag
) =
@_
;
my
@record_blocks
=
map
{
$ct
->block(
$_
)}
$ct
->
select
(
-type
=>
'comment'
,
-data_re
=>
'\@\['
.
$tag
.
'\]'
) ;
return
@record_blocks
;
}
sub
block_lines
{
my
$lines
=
""
;
my
@record_blocks
= get_blocks(
$opts_href
->{
'crontag'
}) ;
foreach
my
$block
(
@record_blocks
)
{
$lines
.=
$block
->
dump
;
$lines
.=
"\n"
;
}
@record_blocks
= get_blocks(
$opts_href
->{
'crontag_iplay'
}) ;
foreach
my
$block
(
@record_blocks
)
{
$lines
.=
$block
->
dump
;
$lines
.=
"\n"
;
}
if
(
keys
%rec_files
)
{
$lines
.=
"\n"
;
$lines
.=
"== Record Files ==\n"
;
$lines
.=
"\n"
;
foreach
my
$file
(
sort
keys
%rec_files
)
{
$lines
.=
"+---[ $opts_href->{'run_dir'}/$file ]------------\n"
;
$lines
.=
"|\n"
;
foreach
my
$line
(@{
$rec_files
{
$file
}})
{
$lines
.=
"| $line\n"
;
}
$lines
.=
"+-------------------------------------------------------------------------------------\n\n"
;
}
}
if
(
keys
%iplay_files
)
{
$lines
.=
"\n"
;
$lines
.=
"== IPLAY Record Files ==\n"
;
$lines
.=
"\n"
;
foreach
my
$file
(
sort
keys
%iplay_files
)
{
$lines
.=
"+---[ $opts_href->{'run_dir'}/$file ]------------\n"
;
$lines
.=
"|\n"
;
foreach
my
$line
(@{
$iplay_files
{
$file
}})
{
$lines
.=
"| $line\n"
;
}
$lines
.=
"+-------------------------------------------------------------------------------------\n\n"
;
}
}
return
$lines
;
}
sub
display_blocks
{
my
@record_blocks
= get_blocks(
$opts_href
->{
'crontag'
}) ;
print
"\n\nBlocks:\n"
;
foreach
my
$block
(
@record_blocks
)
{
print
"\n------------\n"
,
$block
->
dump
;
}
@record_blocks
= get_blocks(
$opts_href
->{
'crontag_iplay'
}) ;
print
"\n\nIPLAY Blocks:\n"
;
foreach
my
$block
(
@record_blocks
)
{
print
"\n------------\n"
,
$block
->
dump
;
}
}
sub
update
{
my
(
$recording_aref
) =
@_
;
my
@record_blocks
= get_blocks(
$opts_href
->{
'crontag'
}) ;
$ct
->remove(
@record_blocks
) ;
create_blocks(
$recording_aref
) ;
}
sub
update_iplay
{
my
(
$recording_aref
) =
@_
;
my
@record_blocks
= get_blocks(
$opts_href
->{
'crontag_iplay'
}) ;
$ct
->remove(
@record_blocks
) ;
create_iplay_blocks(
$recording_aref
) ;
}
sub
commit
{
if
(! -d
"$opts_href->{run_dir}"
)
{
mkpath(
"$opts_href->{run_dir}"
) or
die
"Error: Unable to create run directory $opts_href->{run_dir} : $!"
;
}
foreach
my
$f
(
glob
(
"$opts_href->{run_dir}/*$opts_href->{run_ext}"
))
{
if
(-f
$f
)
{
unlink
$f
;
}
}
if
(
keys
%rec_files
)
{
foreach
my
$file
(
sort
keys
%rec_files
)
{
my
$path
=
"$opts_href->{run_dir}/$file"
;
open
my
$fh
,
">$path"
or
die
"Error: Unable to create run file $path : $!"
;
foreach
my
$line
(@{
$rec_files
{
$file
}})
{
print
$fh
"$line\n"
;
}
close
$fh
;
}
}
if
(
keys
%iplay_files
)
{
foreach
my
$file
(
sort
keys
%iplay_files
)
{
my
$path
=
"$opts_href->{run_dir}/$file"
;
open
my
$fh
,
">$path"
or
die
"Error: Unable to create run file $path : $!"
;
foreach
my
$line
(@{
$iplay_files
{
$file
}})
{
print
$fh
"$line\n"
;
}
close
$fh
;
}
}
$ct
->
write
()
or
do
{
warn
"Error: "
.
$ct
->error .
"\n"
;
};
}
sub
recorded_files
{
return
\
%recorded_files
;
}
sub
create_blocks
{
my
(
$db_aref
) =
@_
;
Linux::DVB::DVBT::Apps::QuartzPVR::Base::DbgTrace::startfn(
'Crontab::create_blocks'
) ;
my
$MAX_TIMESLIP
=
$opts_href
->{
'max_timeslip'
} ;
my
$MAX_TIMESLIP_SECS
=
$MAX_TIMESLIP
* 60 ;
my
$PAD
=
$opts_href
->{
'padding'
} ;
my
$PAD_SECS
=
$PAD
* 60 ;
$opts_href
->{
'app'
}->prt_data(
"create_blocks() db_aref"
,
$db_aref
)
if
$debug
>=3 ;
my
%db
;
foreach
my
$entry_href
(
@$db_aref
)
{
my
$adap
=
$entry_href
->{
'adapter'
} ;
$db
{
$adap
} ||= [] ;
push
@{
$db
{
$adap
}},
$entry_href
;
}
my
@blocks
;
foreach
my
$adap
(
keys
%db
)
{
my
@sorted
=
sort
{ Linux::DVB::DVBT::Apps::QuartzPVR::Prog::start_cmp(
$a
,
$b
) } @{
$db
{
$adap
}} ;
my
$last_entry
=
scalar
(
@sorted
)-1 ;
for
(
my
$i
=0;
$i
<=
$last_entry
; ++
$i
)
{
my
@progs
= (
$sorted
[
$i
]) ;
if
(
$sorted
[
$i
]->{
'type'
} eq
'multiplex'
)
{
push
@progs
, @{
$sorted
[
$i
]->{
'multiplex'
}} ;
}
if
(
$i
==0)
{
foreach
my
$prog_href
(
@progs
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::pad(
$prog_href
,
'start'
,
$PAD
) ;
}
}
else
{
foreach
my
$prog_href
(
@progs
)
{
if
(Linux::DVB::DVBT::Apps::QuartzPVR::Prog::check_pad(
$sorted
[
$i
-1],
$prog_href
,
$PAD
))
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::pad(
$prog_href
,
'start'
,
$PAD
) ;
}
}
}
}
for
(
my
$i
=0;
$i
<=
$last_entry
; ++
$i
)
{
my
@progs
= (
$sorted
[
$i
]) ;
if
(
$sorted
[
$i
]->{
'type'
} eq
'multiplex'
)
{
push
@progs
, @{
$sorted
[
$i
]->{
'multiplex'
}} ;
}
if
(
$i
==
$last_entry
)
{
foreach
my
$prog_href
(
@progs
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::pad(
$prog_href
,
'end'
,
$PAD
) ;
}
}
else
{
foreach
my
$prog_href
(
@progs
)
{
my
$diff_secs
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::timediff_secs(
$prog_href
,
$sorted
[
$i
+1]) ;
if
(
$diff_secs
>=
$PAD_SECS
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::pad(
$prog_href
,
'end'
,
$PAD
) ;
}
else
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::finish_early(
$prog_href
,
$opts_href
->{
'early'
}) ;
}
}
}
}
for
(
my
$i
=0;
$i
<=
$last_entry
; ++
$i
)
{
my
@progs
= (
$sorted
[
$i
]) ;
if
(
$sorted
[
$i
]->{
'type'
} eq
'multiplex'
)
{
push
@progs
, @{
$sorted
[
$i
]->{
'multiplex'
}} ;
}
if
(
$i
==
$last_entry
)
{
foreach
my
$prog_href
(
@progs
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::timeslip(
$prog_href
,
$MAX_TIMESLIP
) ;
}
}
else
{
foreach
my
$prog_href
(
@progs
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::timeslip(
$prog_href
, 0) ;
my
$diff_secs
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::timediff_secs(
$prog_href
,
$sorted
[
$i
+1]) ;
if
(
$MAX_TIMESLIP
)
{
if
(
$diff_secs
>
$MAX_TIMESLIP_SECS
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::timeslip(
$prog_href
,
$MAX_TIMESLIP
) ;
}
elsif
(
$diff_secs
>
$PAD_SECS
)
{
Linux::DVB::DVBT::Apps::QuartzPVR::Prog::timeslip(
$prog_href
,
$diff_secs
/ 60) ;
}
}
}
}
}
foreach
my
$entry_href
(
@sorted
)
{
if
(
$entry_href
->{
'type'
} eq
'multiplex'
)
{
push
@blocks
, create_mux_block(
$entry_href
->{
'id'
},
$entry_href
) ;
}
else
{
push
@blocks
, create_block(
$entry_href
->{
'id'
},
$entry_href
) ;
}
}
}
%rec_files
= () ;
@blocks
=
sort
{
$a
->{
'start_dt_mins'
} <=>
$b
->{
'start_dt_mins'
} }
@blocks
;
foreach
my
$block_href
(
@blocks
)
{
next
unless
(
$block_href
->{
'start_dt_mins'
} >=
$today_mins
) ;
my
$block
= new Config::Crontab::Block ;
$block
->
last
(new Config::Crontab::Comment(
$block_href
->{
'comment'
})) ;
$block
->
last
(new Config::Crontab::Event(
-active
=> 1,
-datetime
=>
$block_href
->{
'datetime'
},
-command
=>
$block_href
->{
'command'
},
)) ;
$ct
->
last
(
$block
) ;
if
(
exists
(
$block_href
->{
'rec_file'
}))
{
my
$file
=
$block_href
->{
'rec_file'
} ;
$rec_files
{
$file
} =
$block_href
->{
'rec_contents'
} ;
}
}
}
sub
create_iplay_blocks
{
my
(
$db_aref
) =
@_
;
Linux::DVB::DVBT::Apps::QuartzPVR::Base::DbgTrace::startfn(
'Crontab::create_iplay_blocks'
) ;
my
@sorted
=
sort
{ Linux::DVB::DVBT::Apps::QuartzPVR::Prog::start_cmp(
$a
,
$b
) } @{
$db_aref
} ;
$opts_href
->{
'app'
}->prt_data(
"create_iplay_blocks() db_aref"
,
$db_aref
)
if
$debug
>=3 ;
%iplay_files
= () ;
my
@blocks
;
my
%blocks
;
foreach
my
$entry_href
(
@sorted
)
{
my
$block_href
= create_iplay_block(
$entry_href
->{
'id'
},
$entry_href
) ;
if
(!
exists
(
$blocks
{
$block_href
->{
'id'
}}))
{
push
@blocks
,
$block_href
;
}
$blocks
{
$block_href
->{
'id'
}} =
$block_href
;
}
@blocks
=
sort
{
$a
->{
'start_dt_mins'
} <=>
$b
->{
'start_dt_mins'
} }
@blocks
;
foreach
my
$block_href
(
@blocks
)
{
next
unless
(
$block_href
->{
'start_dt_mins'
} >=
$today_mins
) ;
my
$block
= new Config::Crontab::Block ;
$block
->
last
(new Config::Crontab::Comment(
$block_href
->{
'comment'
})) ;
$block
->
last
(new Config::Crontab::Event(
-active
=> 1,
-datetime
=>
$block_href
->{
'datetime'
},
-command
=>
$block_href
->{
'command'
},
)) ;
$ct
->
last
(
$block
) ;
}
}
sub
create_block
{
my
(
$id
,
$entry_href
) =
@_
;
my
$type
=
$entry_href
->{
'chan_type'
} ;
my
$cmd
;
my
$fname
= Linux::DVB::DVBT::Apps::QuartzPVR::Series::get_filename(
$entry_href
) ;
$cmd
=
$opts_href
->{
'recprog'
} ;
$cmd
.=
" -a $entry_href->{adapter}"
;
if
(
$entry_href
->{
'timeslip'
})
{
$cmd
.=
" -event $entry_href->{event} -timeslip $entry_href->{'timeslip'}"
;
}
if
(
$type
eq
'radio'
)
{
$cmd
.=
" -title '$entry_href->{title}'"
;
my
$episode
= Linux::DVB::DVBT::Apps::QuartzPVR::Path::episode_string(
$entry_href
) ;
$cmd
.=
" -episode '$episode'"
if
$episode
;
}
my
$pid
=
$entry_href
->{
'pid'
} ;
$cmd
.=
" -id $pid"
;
$cmd
.=
" '$entry_href->{channel}'"
;
my
$recfilename
=
$fname
;
$cmd
.=
" '$recfilename'"
;
$cmd
.=
" $entry_href->{duration_secs}"
;
my
$screen_size
=
$entry_href
->{
'video'
} ;
$cmd
.=
" >> $opts_href->{log_dir}/dvbt-record.log 2>&1"
;
my
$datetime
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_format(
$entry_href
->{
'start_datetime'
},
"%M %H %d %m *"
) ;
my
$block_id
=
$entry_href
->{
'id'
} ||
$entry_href
->{
'rid'
} ;
my
$block_comment
=
"# \@[$opts_href->{'crontag'}] id:$block_id title:\"$entry_href->{title}\" date:$entry_href->{date} start:$entry_href->{start} end:$entry_href->{end} duration:$entry_href->{duration} (video $screen_size) [$type]"
;
my
$block_href
= {
'comment'
=>
$block_comment
,
'datetime'
=>
$datetime
,
'command'
=>
$cmd
,
'start_dt_mins'
=>
$entry_href
->{
'start_dt_mins'
},
} ;
$recorded_files
{
"$pid-dvbt"
} = {
%$entry_href
,
'rectype'
=>
'dvbt'
,
'type'
=>
$type
,
'file'
=>
$recfilename
,
} ;
return
$block_href
;
}
sub
create_iplay_block
{
my
(
$id
,
$entry_href
) =
@_
;
my
(
$fdir
,
$file
) = Linux::DVB::DVBT::Apps::QuartzPVR::Series::get_filename(
$entry_href
) ;
my
(
$iplay_cmd
,
$iplay_comment
) ;
my
$type
=
$entry_href
->{
'chan_type'
} ;
$iplay_cmd
.=
" --type $type"
;
my
$dir
=
$fdir
;
$iplay_cmd
.=
" --output '$dir'"
;
my
$title
=
$entry_href
->{
'title'
} ;
$iplay_cmd
.=
" --get '$title'"
;
my
$pid
=
$entry_href
->{
'pid'
} ;
$iplay_cmd
.=
" -id $pid"
;
my
$subtitle
=
$entry_href
->{
'subtitle'
} ||
""
;
$subtitle
=
"($subtitle)"
if
(
$subtitle
) ;
my
$block_id
=
$entry_href
->{
'id'
} ||
$entry_href
->{
'rid'
} ;
$iplay_comment
=
"# id:$block_id title:\"$entry_href->{title}\" $subtitle date:$entry_href->{prog_date} start:$entry_href->{prog_start} duration:$entry_href->{duration} [$type]"
;
my
$iplay_ctrl_file
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_format(
$entry_href
->{
'start_datetime'
},
"iplay-%Y-%m-%d"
.
$opts_href
->{
'run_ext'
}) ;
$iplay_ctrl_file
= Linux::DVB::DVBT::Apps::QuartzPVR::Path::cleanpath(
"$iplay_ctrl_file"
) ;
$iplay_files
{
$iplay_ctrl_file
} ||= [];
push
@{
$iplay_files
{
$iplay_ctrl_file
}},
$iplay_comment
;
push
@{
$iplay_files
{
$iplay_ctrl_file
}},
$iplay_cmd
;
push
@{
$iplay_files
{
$iplay_ctrl_file
}},
""
;
my
$cmd
;
$cmd
=
$opts_href
->{
'iplayprog'
} ;
$cmd
.=
" -file $opts_href->{'run_dir'}/$iplay_ctrl_file"
;
$cmd
.=
" >> $opts_href->{log_dir}/dvbt-iplay.log 2>&1"
;
my
$datetime
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_format(
$entry_href
->{
'start_datetime'
},
"%M %H %d %m *"
) ;
my
$block_comment
=
"# \@[$opts_href->{'crontag_iplay'}]"
;
my
$block_href
= {
'comment'
=>
$block_comment
,
'datetime'
=>
$datetime
,
'command'
=>
$cmd
,
'start_dt_mins'
=>
$entry_href
->{
'start_dt_mins'
},
'id'
=>
"$datetime"
,
} ;
my
$recfilename
=
"$dir"
;
$recorded_files
{
"$pid-iplay"
} = {
%$entry_href
,
'rectype'
=>
'iplay'
,
'type'
=>
$type
,
'file'
=>
$recfilename
,
'adapter'
=> -1,
} ;
return
$block_href
;
}
sub
create_mux_block
{
my
(
$id
,
$mux_href
) =
@_
;
my
$dt
=
$mux_href
->{
'start_datetime'
} ;
my
$start_dt_mins
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2mins(
$dt
) ;
my
$cmd
;
$cmd
=
$opts_href
->{
'recprog'
} ;
$cmd
.=
" -a $mux_href->{adapter}"
;
my
$rec_file
=
sprintf
"mux%03d$opts_href->{run_ext}"
,
$mux_href
->{
'multid'
} ;
$rec_file
= Linux::DVB::DVBT::Apps::QuartzPVR::Path::cleanpath(
"$rec_file"
) ;
$cmd
.=
" -file $opts_href->{'run_dir'}/$rec_file"
;
my
@rec_contents
= () ;
push
@rec_contents
,
"## Multiplex $mux_href->{multid} recording list"
;
push
@rec_contents
,
"## "
;
push
@rec_contents
,
""
;
my
$idx
=0 ;
foreach
my
$entry_href
(@{
$mux_href
->{
'multiplex'
}})
{
my
$entry
=
""
;
my
$datetime
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_format(
$entry_href
->{
'start_datetime'
},
"%M %H %d %m *"
) ;
my
$block_id
=
$entry_href
->{
'id'
} ||
$entry_href
->{
'rid'
} ;
my
$block_comment
=
"# event:$entry_href->{event} id:$block_id title:\"$entry_href->{title}\" date:$entry_href->{date} start:$entry_href->{start} end:$entry_href->{end} duration:$entry_href->{duration}"
;
if
(
$idx
)
{
$dt
=
$entry_href
->{
'start_datetime'
} ;
my
$entry_start_dt_mins
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2mins(
$dt
) ;
my
$offset
= (
$entry_start_dt_mins
-
$start_dt_mins
) *60 ;
$entry
.=
"+$offset\t"
;
}
else
{
$entry
.=
" \t"
;
}
my
$end_dt
=
$entry_href
->{
'end_datetime'
} ;
$block_comment
.=
" ("
. Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2hms(
$dt
) .
" - "
. Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2hms(
$end_dt
) .
" Duration: "
. Linux::DVB::DVBT::Apps::QuartzPVR::Time::secs2time(
$entry_href
->{duration_secs}) .
")"
;
my
$fname
= Linux::DVB::DVBT::Apps::QuartzPVR::Series::get_filename(
$entry_href
) ;
my
$type
=
$entry_href
->{
'chan_type'
} ;
$entry
.=
" '$entry_href->{channel}'"
;
my
$recfilename
=
$fname
;
$entry
.=
" '$recfilename'"
;
$entry
.=
" $entry_href->{duration_secs}"
;
if
(
$entry_href
->{
'timeslip'
})
{
$entry
.=
" \t-event $entry_href->{event} -timeslip $entry_href->{'timeslip'}"
;
}
if
(
$type
eq
'radio'
)
{
$entry
.=
" -title '$entry_href->{title}'"
;
my
$episode
= Linux::DVB::DVBT::Apps::QuartzPVR::Path::episode_string(
$entry_href
) ;
$entry
.=
" -episode '$episode'"
if
$episode
;
}
my
$pid
=
$entry_href
->{
'pid'
} ;
$entry
.=
" -id $pid"
;
++
$idx
;
push
@rec_contents
,
$block_comment
;
push
@rec_contents
,
$entry
;
push
@rec_contents
,
""
;
$recorded_files
{
"$pid-dvbt"
} = {
%$entry_href
,
'rectype'
=>
'dvbt'
,
'type'
=>
$type
,
'file'
=>
$recfilename
,
} ;
}
my
$datetime
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_format(
$mux_href
->{
'start_datetime'
},
"%M %H %d %m *"
) ;
$cmd
.=
" >> $opts_href->{log_dir}/dvbt-record.log 2>&1"
;
my
$block_comment
=
"# \@[$opts_href->{'crontag'}] MULTIPLEX$mux_href->{multid} date:$mux_href->{date} start:$mux_href->{start} end:$mux_href->{end} duration:$mux_href->{duration}"
;
my
$block_href
= {
'comment'
=>
$block_comment
,
'datetime'
=>
$datetime
,
'command'
=>
$cmd
,
'start_dt_mins'
=>
$start_dt_mins
,
'rec_file'
=>
$rec_file
,
'rec_contents'
=> \
@rec_contents
,
} ;
return
$block_href
;
}
sub
check_cron
{
Linux::DVB::DVBT::Apps::QuartzPVR::Base::DbgProf::startfn() ;
print
"check_cron()\n"
if
$debug
;
my
@record_blocks
=
map
{
$ct
->block(
$_
)}
$ct
->
select
(
-type
=>
'comment'
,
-data_re
=>
'\@\['
.
$opts_href
->{
'crontag'
} .
'\]'
) ;
my
%cron
= (
'0'
=> {},
'1'
=> {},
);
foreach
my
$block
(
@record_blocks
)
{
for
my
$event
(
$block
->
select
(
-type
=>
'event'
) )
{
my
$cmd
=
$event
->command() ;
my
$hour
=
$event
->hour() ;
my
$min
=
$event
->minute() ;
my
$day
=
$event
->dom() ;
my
$month
=
$event
->month() ;
my
$adap
=
"0"
;
my
$duration_secs
= 0 ;
my
$chan
;
my
$prog
;
my
$found
= 0 ;
print
"cmd=\"$cmd\"\n"
if
$debug
;
if
(
$cmd
=~ /(?:dvbt\-ffrecord|dvbt\-ffrecord\.pl) \-a (\d+) \'([^\']+)\' \'([^\']+)\' (\d+)/)
{
(
$adap
,
$chan
,
$prog
,
$duration_secs
) = ($1, $2, $3, $4) ;
$adap
=
sprintf
"%0d"
,
$adap
;
++
$found
;
print
" + got (adap=$adap, chan=$chan, prog=$prog, secs=$duration_secs)\n"
if
$debug
;
}
elsif
(
$cmd
=~ /^dvbt\-ffrecord \'([^\']+)\' \'([^\']+)\' (\d+)/)
{
(
$chan
,
$prog
,
$duration_secs
) = ($1, $2, $3) ;
++
$found
;
print
" + got (chan=$chan, prog=$prog, secs=$duration_secs)\n"
if
$debug
;
}
next
unless
$found
;
my
$date
=
"2010/$month/$day"
;
my
$time
=
sprintf
"%02d:%02d"
,
$hour
,
$min
;
my
$dt
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::parse_date(
$date
,
$time
) ;
my
$dt_mins
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2mins(
$dt
) ;
my
$dt_end
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt_offset(
$dt
,
"+ $duration_secs seconds"
) ;
my
$end_time
= Linux::DVB::DVBT::Apps::QuartzPVR::Time::dt2hms(
$dt_end
) ;
print
"date=$date time=$time dt=$dt dt-end=$dt_end end=$end_time mins=$dt_mins\n"
if
$debug
;
my
$start
= 60 *
$dt_mins
;
my
$end
=
$start
+
$duration_secs
;
print
"start=$start end=$end\n"
if
$debug
;
$cron
{
$adap
}{
$dt_mins
} ||= [] ;
push
@{
$cron
{
$adap
}{
$dt_mins
}}, {
'date'
=>
$date
,
'time'
=>
$time
,
'chan'
=>
$chan
,
'prog'
=>
$prog
,
'duration'
=>
$duration_secs
,
'start'
=>
$start
,
'end'
=>
$end
,
'endtime'
=>
$end_time
,
} ;
}
}
foreach
my
$adap
(
sort
{
$a
<=>
$b
}
keys
%cron
)
{
my
$dvb
=
"DVB$adap"
;
my
$prev_end
= 0 ;
my
$prev
;
foreach
my
$dt_mins
(
sort
{
$a
<=>
$b
}
keys
%{
$cron
{
$adap
}})
{
if
(
scalar
(@{
$cron
{
$adap
}{
$dt_mins
}}) > 1)
{
print
"ERROR: multiple programs scheduled at the same time on $dvb:\n"
;
foreach
my
$entry
(@{
$cron
{
$adap
}{
$dt_mins
}})
{
print
" $entry->{'date'} $entry->{'prog'} $entry->{'time'} - $entry->{'endtime'} : '$entry->{'title'}' $entry->{'chan'} ($entry->{'type'})\n"
;
}
print
"\n"
;
}
else
{
my
$entry
=
$cron
{
$adap
}{
$dt_mins
}[0] ;
my
$error
=
""
;
if
(
$entry
->{
'start'
} <=
$prev_end
)
{
$error
=
"program overlap"
;
}
elsif
(
$entry
->{
'start'
} -
$prev_end
<
$opts_href
->{
'early'
})
{
$error
=
"programs are too close (less than $opts_href->{'early'} secs)"
;
}
if
(
$error
)
{
print
"ERROR: $error on $dvb:\n"
;
print
" $entry->{'date'} $entry->{'prog'} $entry->{'time'} - $entry->{'endtime'}\n"
;
print
" $entry->{'date'} $prev->{'prog'} $prev->{'time'} - $prev->{'endtime'}\n"
;
print
"\n"
;
}
$prev_end
=
$entry
->{
'end'
} ;
$prev
=
$entry
;
}
}
}
Linux::DVB::DVBT::Apps::QuartzPVR::Base::DbgProf::endfn() ;
}
1;