#!/usr/bin/perl
our
$VERSION
=
'2.00'
;
our
$DEBUG
=0;
our
$APP
;
our
@info_lines
;
our
$progname
;
our
$dvb_name
;
$APP
= App::Framework->new() ;
$APP
->go() ;
sub
app
{
my
(
$app
,
$opts_href
) =
@_
;
$DEBUG
=
$opts_href
->{
'debug'
} ;
Linux::DVB::DVBT->debug(
$DEBUG
) ;
Linux::DVB::DVBT->dvb_debug(
$opts_href
->{
'dvb-debug'
}) ;
$Linux::DVB::DVBT::DEBUG
=
$DEBUG
;
Linux::DVB::DVBT->verbose(
$opts_href
->{
'verbose'
} ? 2 : 0) ;
my
$sql
=
$app
->sql() ;
my
$dvb
= Linux::DVB::DVBT->new(
'adapter_num'
=>
$opts_href
->{
'adapter'
},
) ;
$progname
=
$app
->progname ;
$dvb_name
=
sprintf
"DVB%d"
,
$opts_href
->{
'adapter'
} ;
info(
"==============================================================="
) ;
info(
"$progname v$VERSION"
) ;
info(
"Linux::DVB::DVBT v$Linux::DVB::DVBT::VERSION"
) ;
info(
"== Locked $dvb_name =="
) ;
my
(
$epg_href
,
$dates_href
) =
$dvb
->epg() ;
info(
"== Released $dvb_name =="
) ;
$dvb
->dvb_close() ;
$app
->prt_data(
"==EPG=="
,
$epg_href
)
if
$DEBUG
>=2 ;
$app
->prt_data(
"==DATES=="
,
$dates_href
)
if
$DEBUG
>=3 ;
my
$user
=
$opts_href
->{
'user'
} || Linux::DVB::DVBT::Apps::QuartzPVR::Config::Constants::SQL_USER ;
my
$password
=
$opts_href
->{
'password'
} || Linux::DVB::DVBT::Apps::QuartzPVR::Config::Constants::SQL_PASSWORD ;
if
(!
$user
|| !
$password
)
{
print
"Error: You must specify the MySQL username AND password when using this script outside the PVR suite\n"
;
exit
1 ;
}
my
%sql_vars
;
$app
->sql->set(
'database'
=>
$opts_href
->{
'database'
},
'table'
=>
$opts_href
->{
'table'
},
'user'
=>
$user
,
'password'
=>
$password
,
'trace'
=>
$opts_href
->{
'debug'
},
'trace'
=>
$opts_href
->{
'dbg-sql'
},
'trace_file'
=>
'logsql.log'
,
'debug'
=>
$opts_href
->{
'dbg-sql'
},
'prepare'
=> {
'insert'
=> {
'vars'
=> [
qw/pid event channel title date start duration episode num_episodes text genre tva_prog tva_series audio video subtitles/
],
'vals'
=> \
%sql_vars
,
},
'update'
=> {
'vars'
=> [
qw/event title date start duration text episode num_episodes text genre tva_prog tva_series audio video subtitles/
],
'vals'
=> \
%sql_vars
,
'where'
=> {
'vars'
=> [
qw/pid channel/
],
'vals'
=> \
%sql_vars
},
'limit'
=> 1,
},
'check'
=> {
'limit'
=> 1,
'where'
=> {
'vars'
=> [
qw/pid channel/
],
'vals'
=> \
%sql_vars
},
},
'select_channels'
=> {
'table'
=>
'channels'
,
},
},
) ;
info(
"Updating database:"
) ;
if
(
$opts_href
->{
'del-old'
})
{
my
$del_old_query
=
"DELETE FROM $opts_href->{table} WHERE "
.
"`date` <= ( SELECT DATE_SUB(CURDATE(), INTERVAL 1 MONTH) )"
;
$app
->sql->
do
(
$del_old_query
)
unless
$opts_href
->{
'skip-sql'
} ;
}
my
$new_eit
= 0 ;
foreach
my
$chan
(
sort
keys
%$epg_href
)
{
info(
" $chan..."
) ;
next
unless
$chan
;
my
$del_query
=
"DELETE FROM $opts_href->{table} WHERE "
.
"`channel`='$chan' AND ("
.
"(`date` = '$dates_href->{$chan}{start_date}' AND `start` >= '$dates_href->{$chan}{start}') "
.
"OR (`date` > '$dates_href->{$chan}{start_date}' AND `date` <= '$dates_href->{$chan}{end_date}') "
.
")"
;
print
"$chan : $del_query\n"
if
(
$opts_href
->{
'debug'
});
$app
->sql->
do
(
$del_query
)
unless
$opts_href
->{
'skip-sql'
} ;
next
if
$chan
=~ /^(\d+)\-(\d+)$/ ;
print
"PROCESSING $chan : \n"
if
(
$opts_href
->{
'debug'
});
++
$new_eit
;
my
@sorted
;
foreach
my
$pid
(
keys
%{
$epg_href
->{
$chan
}})
{
next
unless
$pid
;
my
$entry_href
=
$epg_href
->{
$chan
}{
$pid
} ;
my
$date
= reformat_date(
$entry_href
->{
'date'
}) ;
my
$dt
= parse_date(
$entry_href
->{date},
$entry_href
->{start}) ;
$entry_href
->{
'start_dt_mins'
} = dt2mins(
$dt
) ;
}
@sorted
=
sort
{start_cmp(
$epg_href
->{
$chan
}{
$a
},
$epg_href
->{
$chan
}{
$b
} )}
keys
%{
$epg_href
->{
$chan
}} ;
foreach
my
$pid
(
@sorted
)
{
next
unless
$pid
;
my
$entry_href
=
$epg_href
->{
$chan
}{
$pid
} ;
my
$episode
;
my
$num_episodes
;
if
(
exists
(
$entry_href
->{
'episode'
}))
{
$episode
=
int
(
$entry_href
->{
'episode'
}) ;
$num_episodes
=
int
(
$entry_href
->{
'num_episodes'
}) ;
}
my
$episode_str
=
$episode
?
"$episode / $num_episodes"
:
""
;
sql_prepare_vals(
$entry_href
, \
%sql_vars
) ;
my
@results
;
@results
=
$app
->sql->sth_query_all(
'check'
)
unless
$opts_href
->{
'skip-sql'
} ;
if
(
@results
)
{
info(
" Update: $sql_vars{'channel'} [$pid] $entry_href->{'title'} @ $entry_href->{'start'} on $entry_href->{'date'} $episode_str"
) ;
$app
->sql->sth_query(
'update'
)
unless
$opts_href
->{
'skip-sql'
} ;
}
else
{
info(
" New: $sql_vars{'channel'} [$pid] $entry_href->{'title'} @ $entry_href->{'start'} on $entry_href->{'date'} $episode_str"
) ;
$app
->sql->sth_query(
'insert'
)
unless
$opts_href
->{
'skip-sql'
} ;
}
set_times(
$entry_href
) ;
info(
"#@# $pid | $sql_vars{'channel'} | $entry_href->{'date'} | $entry_href->{'start'} .. $entry_href->{'end'} | $entry_href->{'title'} | "
) ;
}
}
info(
"Processed $new_eit programs"
) ;
info(
"COMPLETE"
) ;
}
sub
timestamp
{
my
(
$sec
,
$min
,
$hour
,
$mday
,
$mon
,
$year
,
$wday
,
$yday
,
$isdst
) =
localtime
(
time
);
return
sprintf
"%02d:%02d:%02d %02d/%02d/%04d"
,
$hour
,
$min
,
$sec
,
$mday
,
$mon
+1,
$year
+1900;
}
sub
prompt
{
my
$timestamp
= timestamp() ;
my
$prompt
=
"[$progname ($$) $timestamp $dvb_name]"
;
return
$prompt
;
}
sub
info
{
my
(
$msg
) =
@_
;
my
$prompt
= prompt() ;
$msg
=~ s/\n/\n
$prompt
/g ;
print
STDERR
"$prompt $msg\n"
;
push
@info_lines
,
$msg
;
}
sub
error_mail
{
my
(
$to
,
$error
,
$channel
,
$file
,
$log
) =
@_
;
my
$prompt
= prompt() ;
my
$data
=
"echo '$error'"
;
my
$tmpfile
=
"/tmp/dvbt-ffrec.$$"
;
if
(
open
my
$fh
,
">$tmpfile"
)
{
print
$fh
"$error\n\n"
;
foreach
(
@info_lines
)
{
print
$fh
"$_\n"
;
}
close
$fh
;
$data
=
"cat $tmpfile"
;
}
else
{
$tmpfile
=
undef
;
}
`
$data
| mail -s
'$prompt $channel $file Error'
$to
` ;
unlink
$tmpfile
if
$tmpfile
;
}
sub
die_error_mail
{
my
(
$to
,
$error
,
$channel
,
$file
,
$log
) =
@_
;
error_mail(
$to
,
$error
,
$channel
,
$file
,
$log
) ;
info(
"FATAL: $error"
) ;
exit
1 ;
}
sub
time2mins
{
my
(
$time
) =
@_
;
my
$mins
= 0 ;
if
(
$time
=~ /^(\d+):(\d+):(\d+)/)
{
$mins
= $1*60 + $2 ;
}
elsif
(
$time
=~ /^(\d+):(\d+)/)
{
$mins
= $1*60 + $2 ;
}
elsif
(
$time
=~ /^(\d+)/)
{
$mins
= $1 ;
}
return
$mins
;
}
sub
sql_prepare_vals
{
my
(
$href
,
$sql_vars_href
) =
@_
;
foreach
my
$key
(
keys
%$sql_vars_href
)
{
$sql_vars_href
->{
$key
} =
''
;
}
foreach
my
$key
(
keys
%$href
)
{
my
$val
=
$href
->{
$key
} ;
$sql_vars_href
->{
$key
} =
$val
if
defined
(
$val
) ;
}
$sql_vars_href
->{
'text'
} .=
$sql_vars_href
->{
'etext'
} ;
$sql_vars_href
->{
'title'
} ||=
'(no program)'
;
$sql_vars_href
->{
'episode'
} ||= 0 ;
$sql_vars_href
->{
'num_episodes'
} ||= 0 ;
$sql_vars_href
->{
'tva_prog'
} ||=
'-'
;
$sql_vars_href
->{
'tva_series'
} ||=
'-'
;
$sql_vars_href
->{
'subtitles'
} = 0 ;
$sql_vars_href
->{
'audio'
} =
'unknown'
;
$sql_vars_href
->{
'video'
} =
'unknown'
;
if
(
exists
(
$href
->{
'flags'
}))
{
$sql_vars_href
->{
'subtitles'
} =
$href
->{
'flags'
}{
'subtitles'
} || 0 ;
foreach
my
$audio
(
qw/surround multi dual-mono stereo mono/
)
{
if
(
$href
->{
'flags'
}{
$audio
})
{
$sql_vars_href
->{
'audio'
} =
$audio
;
last
;
}
}
foreach
my
$video
(
qw/hdtv 16:9 4:3/
)
{
if
(
$href
->{
'flags'
}{
$video
})
{
$sql_vars_href
->{
'video'
} =
uc
$video
;
last
;
}
}
}
if
(
$sql_vars_href
->{
'pid'
} =~ /^([\d]+)\-/)
{
$sql_vars_href
->{
'event'
} = $1 ;
}
$sql_vars_href
->{
'chan_type'
} =
'tv'
;
$APP
->prt_data(
"sql_prepare_vals() src="
,
$href
,
" dest="
,
$sql_vars_href
,
"\n"
)
if
$DEBUG
;
}
sub
reformat_date
{
my
(
$date
) =
@_
;
$date
=~ s%-%/
%g
;
return
$date
;
}
sub
parse_date
{
my
(
$date
,
$time
) =
@_
;
$time
||=
""
;
my
$dt
= ParseDate(
"$date $time"
) ;
return
$dt
;
}
sub
dt_format
{
my
(
$dt
,
$fmt
) =
@_
;
return
UnixDate(
$dt
,
$fmt
) ;
}
sub
dt2mins
{
my
(
$dt
) =
@_
;
my
$secs
= dt_format(
$dt
,
"%s"
) ;
my
$mins
=
int
(
$secs
/ 60) ;
return
$mins
;
}
sub
start_cmp
{
my
(
$a
,
$b
) =
@_
;
return
$a
->{
'start_dt_mins'
} <=>
$b
->{
'start_dt_mins'
} ;
}
sub
dt_offset
{
my
(
$dt
,
$offset
) =
@_
;
my
$err
;
$dt
= DateCalc(
$dt
,
$offset
, \
$err
) ;
print
"Date calc error ($offset): $err\n"
if
(
$err
) ;
return
$dt
;
}
sub
dt2hm
{
my
(
$dt
) =
@_
;
my
$time
= dt_format(
$dt
,
"%H:%M"
) ;
return
$time
;
}
sub
set_times
{
my
(
$entry_href
) =
@_
;
my
$duration_mins
= time2mins(
$entry_href
->{
'duration'
}) ;
my
$duration_add
=
sprintf
"+ %dmin"
,
$duration_mins
;
my
$dt
= parse_date(
$entry_href
->{date},
$entry_href
->{start}) ;
$dt
= dt_offset(
$dt
,
$duration_add
) ;
$entry_href
->{
'end'
} = dt2hm(
$dt
) ;
}