#!/usr/bin/perl
#
use strict ;
# Local
use App::Framework '+Sql +Run' ;
use Config::Crontab ;
use Linux::DVB::DVBT ;
## MySQL tables current versions
our %table_versions = (
'database' => '1.00',
'channels' => '1.01',
'iplay' => '1.00',
'listings' => '1.00',
'multirec' => '1.00',
'record' => '1.00',
'recorded' => '1.00',
'schedule' => '1.00',
) ;
# VERSION
our $VERSION = '2.03' ;
our $DEBUG = 0 ;
# Create application and run it
App::Framework->new() ;
go() ;
#=================================================================================
# SUBROUTINES EXECUTED BY APP
#=================================================================================
#----------------------------------------------------------------------
# Main execution
#
sub app
{
my ($app, $opts_href, $args_href) = @_ ;
$DEBUG = $opts_href->{'debug'} ;
my %settings = get_config($app) ;
foreach my $var (qw/perl_lib perl_scripts pm_version/)
{
$settings{$var} = $opts_href->{$var} ;
$settings{uc $var} = $opts_href->{$var} ;
}
$app->prt_data("Settings", \%settings) if $DEBUG ;
## Must run this script as root
if ($>)
{
print STDERR "Error: This script must be run as root\n" ;
exit 1 ;
}
my $webowner = "$settings{WEB_USER}:$settings{WEB_GROUP}" ;
my $pvrowner = "$settings{PVR_USER}:$settings{PVR_GROUP}" ;
## Create PVR user
create_pvr_user($app, \%settings) ;
## Create database
create_database($app, \%settings) ;
## Create dirs
create_dirs($app, \%settings) ;
## Copy files
## Set privileges
my @dirs = (
['css', $webowner, 0644],
['js', $webowner, 0644],
['php', $webowner, 0644],
['tpl', $webowner, 0644],
) ;
install_files($app, \%settings, \@dirs) ;
## Amend template files
template_files($app, \%settings, "install/templates.txt") ;
## Start server
start_server($app, \%settings) ;
## Do dvb-t scan
if ( dvbt_scan($app, \%settings) )
{
## Set channels
dvbt_channels($app, \%settings) ;
## Get listings
dvbt_listings($app, \%settings) ;
}
else
{
print "!! Please re-run after adding a DVB-T adapter, I can then update the channel information and the EPG !!\n" ;
}
}
#----------------------------------------------------------------------
# PVR Linux user
#
sub create_pvr_user
{
my ($app, $settings_href) = @_ ;
print "Creating user ..\n" ;
my $user = $settings_href->{'PVR_USER'} ;
my $group = $settings_href->{'PVR_GROUP'} ;
my $home = $settings_href->{'PVR_HOME'} ;
my $perl_scripts = $settings_href->{'PERL_SCRIPTS'} ;
my $logdir = $settings_href->{'PVR_LOGDIR'} ;
# my $uid = getpwnam($user) ;
my ($uname, $upasswd, $uid, $ugid, $quota,
$comment, $gcos, $dir, $shell) = getpwnam($user) ;
my ($gname,$gpasswd,$gid,$members) = getgrnam($group) ;
print "user=$user : uid=$uid name=$uname gid=$ugid dir=$dir\n" if $DEBUG ;
print "group=$group : name=$gname gid=$gid members='$members'\n" if $DEBUG ;
## Create group if required
if (!$gid)
{
runit($app,
"groupadd $group",
"Creating group $group",
) ;
}
## Create user if required
my $system_user = 0 ;
if (!$uid)
{
runit($app,
"useradd -c 'Quartz PVR' -r -d $home -m -k /dev/null -g $group $user",
"Creating user $user",
) ;
$system_user=1 ;
}
($uname, $upasswd, $uid, $ugid, $quota,
$comment, $gcos, $dir, $shell) = getpwnam($user) ;
($gname,$gpasswd,$gid,$members) = getgrnam($group) ;
print "NOW user=$user : uid=$uid name=$uname gid=$ugid dir=$dir\n" if $DEBUG ;
print "NOW group=$group : name=$gname gid=$gid members='$members'\n" if $DEBUG ;
## Add user to group if required
# check user's primary group id matches group id
# OR user is in the members list of the group
if ( ($ugid != $gid) && ($members !~ /\b$user\b/) )
{
my $stat = try_runit($app,
"usermod -a -G $group $user"
) ;
if ($stat)
{
runit($app,
"usermod -A -G $group $user",
"Adding user $user to group $group",
) ;
}
}
## Ensure crontab is initialised
my $crontag = "@[dvbt-update]" ;
my %blocks = (
"# $crontag Update the EPG" => {
-active => 1,
-minute => 7,
-hour => 4,
-dow => "*",
-month => "*",
-dom => "*",
-command => "$perl_scripts/dvbt-epg-sql >> $logdir/dvbt_epg.log 2>&1",
},
"# $crontag Update the scheduled programs" => {
-active => 1,
-minute => 7,
-hour => 6,
-dow => "*",
-month => "*",
-dom => "*",
-command => "$perl_scripts/dvbt-record-mgr -dbg-trace all -report 1 >> $logdir/dvb_record_mgr.log 2>&1",
},
"# $crontag Clean out trash" => {
-active => 1,
-minute => 0,
-hour => 0,
-dow => "*",
-month => "*",
-dom => "*",
-command => "find $settings_href->{VIDEO_TRASH} -mtime +7|xargs -i rm -rf '{}' 2>&1",
},
) ;
my $crontag_re = $crontag ;
$crontag_re =~ s/([\[\@\-])/\\$1/g ;
my $ct = new Config::Crontab( -owner => $user );
$ct->read() ;
my @dvbt_blocks = $ct->select(
-type => 'comment',
-data_re => $crontag_re,
) ;
Linux::DVB::DVBT::prt_data("dvbt_blocks=", \@dvbt_blocks) if $DEBUG ;
if (@dvbt_blocks)
{
foreach my $block ($ct->blocks)
{
my $tag = "" ;
foreach my $comment ($block->select(-type => 'comment'))
{
$tag = $comment->data() ;
}
if ($tag)
{
next if $tag !~ /$crontag_re/ ;
foreach my $event ($block->select(-type => 'event'))
{
foreach my $field (qw/minute hour dom month dow/)
{
$blocks{$tag} ||= {} ;
$blocks{$tag}{"-$field"} = $event->$field() ;
}
}
## Remove existing block
$ct->remove($block) ;
}
}
}
Linux::DVB::DVBT::prt_data("Blocks=", \%blocks) if $DEBUG ;
foreach my $comment (keys %blocks)
{
## Add block to crontab
my $block = new Config::Crontab::Block ;
$block->last(new Config::Crontab::Comment($comment)) ;
$block->last(new Config::Crontab::Event(%{ $blocks{$comment} })) ;
$ct->first($block) ;
}
## Write crontab
$ct->write()
or do {
warn "Error: " . $ct->error . "\n";
};
print " * Written crontab\n" ;
## Clear out any previous logs
foreach my $log (glob("$home/*.log"))
{
if (-f $log)
{
unlink $log ;
}
}
}
#======================================================================
# MYSQL
#======================================================================
#----------------------------------------------------------------------
# MySQL
#
#
sub create_database
{
my ($app, $settings_href) = @_ ;
print "Setting up MySQL ..\n" ;
my ($results_aref, $status) ;
my $sql ;
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
## Check for user
$sql =<<SQL ;
SELECT user from mysql.user where user='$settings_href->{SQL_USER}';
SQL
$results_aref = mysql_runit($app, $password, $sql, "MySQL error while checking for user") ;
my $create_user = 1 ;
if (@$results_aref)
{
$create_user = 0 ;
}
## Create user if required
if ($create_user)
{
print " * Create user $settings_href->{SQL_USER}\n" ;
$sql =<<SQL ;
CREATE USER '$settings_href->{SQL_USER}'\@'localhost' IDENTIFIED BY '$settings_href->{SQL_PASSWORD}';
GRANT USAGE ON * . * TO '$settings_href->{SQL_USER}'\@'localhost' IDENTIFIED BY '$settings_href->{SQL_PASSWORD}' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `$settings_href->{DATABASE}` /*!40100 DEFAULT CHARACTER SET latin1 */;
GRANT ALL PRIVILEGES ON `$settings_href->{DATABASE}` . * TO '$settings_href->{SQL_USER}'\@'localhost' WITH GRANT OPTION ;
SQL
}
else
{
print " * Update user $settings_href->{SQL_USER}\n" ;
$sql =<<SQL ;
SET PASSWORD FOR '$settings_href->{SQL_USER}'\@'localhost' = PASSWORD('$settings_href->{SQL_PASSWORD}') ;
GRANT USAGE ON * . * TO '$settings_href->{SQL_USER}'\@'localhost' IDENTIFIED BY '$settings_href->{SQL_PASSWORD}' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `$settings_href->{DATABASE}` /*!40100 DEFAULT CHARACTER SET latin1 */;
GRANT ALL PRIVILEGES ON `$settings_href->{DATABASE}` . * TO '$settings_href->{SQL_USER}'\@'localhost' WITH GRANT OPTION ;
SQL
}
$results_aref = mysql_runit($app, $password, $sql, "MySQL error while creating database") ;
## Check for versions
my %versions = (
'database' => '0',
'channels' => '0',
'iplay' => '0',
'listings' => '0',
'multirec' => '0',
'record' => '0',
'recorded' => '0',
'schedule' => '0',
) ;
my $got_versions = 0 ;
$sql =<<SQL ;
SELECT `item`,`version` from $settings_href->{DATABASE}.versions ;
SQL
($results_aref, $status) = mysql_try_runit($app, $password, $sql) ;
if ($status == 0)
{
if (@$results_aref)
{
$got_versions = 1 ;
foreach my $line (@$results_aref)
{
if ($line =~ /(\S+)\s+([\d\.]+)/)
{
my ($var, $ver) = ($1, $2) ;
next if $var eq 'item' ;
$versions{$var} = $ver ;
}
}
}
}
## Check for listings
my $got_listings = 0 ;
$sql =<<SQL ;
SELECT * from $settings_href->{DATABASE}.listings LIMIT 1 ;
SQL
($results_aref, $status) = mysql_try_runit($app, $password, $sql) ;
if ($status == 0)
{
if (@$results_aref)
{
$got_listings = 1 ;
}
}
if ($got_listings)
{
print "Already got listings table, checking table versions...\n" ;
foreach my $table (qw/channels iplay listings multirec record recorded schedule/)
{
my $current_ver = $versions{$table} ;
my $latest_ver = $table_versions{$table} ;
if ($current_ver ne $latest_ver)
{
no strict 'refs' ;
print " * Updating table '$table'\n" ;
my $update_fn = "update_table_$table" ;
&$update_fn($app, $settings_href, $current_ver, $latest_ver) ;
}
}
## Ensure versions table exists
$sql = $app->data("versions.sql") ;
$sql =~ s/\%DATABASE\%/$settings_href->{'DATABASE'}/g ;
mysql_runit($app, $password, $sql, "MySQL error while creating versions table") ;
}
else
{
print "Creating new tables ..\n" ;
## Create tables
$sql = $app->data("sql") . $app->data("versions.sql") ;
$sql =~ s/\%DATABASE\%/$settings_href->{'DATABASE'}/g ;
mysql_runit($app, $password, $sql, "MySQL error while creating tables") ;
}
update_table_versions($app, $settings_href, \%table_versions)
}
#----------------------------------------------------------------------
sub update_table_versions
{
my ($app, $settings_href, $latest_versions_href) = @_ ;
my $table = 'versions' ;
my $sql = "" ;
foreach my $item (keys %$latest_versions_href)
{
$sql .= "UPDATE $settings_href->{DATABASE}.$table SET `version`='$latest_versions_href->{$item}' where `item` = '$item';\n" ;
}
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
mysql_runit($app, $password, $sql, "MySQL error while updating table '$table' to set latest versions") ;
}
#----------------------------------------------------------------------
sub update_table_channels
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
my $table = 'channels' ;
if ($existing_version lt '1.01')
{
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
my $sql =<<SQL ;
ALTER TABLE $settings_href->{DATABASE}.$table CHANGE `chan_type` `chan_type` set('tv','radio','hd-tv') NOT NULL DEFAULT 'tv' COMMENT 'TV or Radio' ;
SQL
mysql_runit($app, $password, $sql, "MySQL error while updating table '$table' to version $latest_version") ;
}
}
#----------------------------------------------------------------------
sub update_table_iplay
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
# no op
}
#----------------------------------------------------------------------
sub update_table_listings
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
# no op
}
#----------------------------------------------------------------------
sub update_table_multirec
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
my $table = 'multirec' ;
if ($existing_version eq '0')
{
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
my $sql =<<SQL ;
ALTER TABLE $settings_href->{DATABASE}.$table CHANGE `adapter` `adapter` VARCHAR( 16 ) NOT NULL DEFAULT '0' ;
SQL
mysql_runit($app, $password, $sql, "MySQL error while updating table '$table' to version $latest_version") ;
}
}
#----------------------------------------------------------------------
sub update_table_record
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
my $table = 'record' ;
if ($existing_version eq '0')
{
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
my $sql =<<SQL ;
ALTER TABLE $settings_href->{DATABASE}.$table DROP `episode`, DROP `num_episodes`, DROP `adapter` ;
SQL
mysql_try_runit($app, $password, $sql) ;
}
}
#----------------------------------------------------------------------
sub update_table_recorded
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
my $table = 'recorded' ;
if ($existing_version eq '0')
{
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
my $sql =<<SQL ;
ALTER TABLE $settings_href->{DATABASE}.$table CHANGE `adapter` `adapter` VARCHAR( 16 ) NOT NULL DEFAULT '0' ;
SQL
mysql_runit($app, $password, $sql, "MySQL error while updating table '$table' to version $latest_version") ;
}
}
#----------------------------------------------------------------------
sub update_table_schedule
{
my ($app, $settings_href, $existing_version, $latest_version) = @_ ;
my $table = 'schedule' ;
if ($existing_version eq '0')
{
my $password = $settings_href->{'SQL_ROOT_PASSWORD'} ;
my $sql =<<SQL ;
ALTER TABLE $settings_href->{DATABASE}.$table CHANGE `adapter` `adapter` VARCHAR( 16 ) NOT NULL DEFAULT '0' ;
SQL
mysql_runit($app, $password, $sql, "MySQL error while updating table '$table' to version $latest_version") ;
}
}
#======================================================================
# INSTALL
#======================================================================
#----------------------------------------------------------------------
# Directories
#
sub create_dirs
{
my ($app, $settings_href) = @_ ;
print "Creating directories:\n" ;
my $web_uid = getpwnam($settings_href->{'WEB_USER'}) ;
my $web_gid = getgrnam($settings_href->{'WEB_GROUP'}) ;
my $pvr_uid = getpwnam($settings_href->{'PVR_USER'}) ;
my $pvr_gid = getgrnam($settings_href->{'PVR_GROUP'}) ;
## Web
foreach my $d (qw/PVR_ROOT/)
{
my $dir = $settings_href->{$d} ;
if (! -d $dir)
{
print " * $dir .. ($settings_href->{'WEB_USER'}:$settings_href->{'WEB_GROUP'})\n" ;
if (!mkpath([$dir], 0, 0755))
{
print "ERROR unable to create dir $dir : $!" ;
exit 1 ;
}
chown $web_uid, $web_gid, $dir ;
}
}
## PVR
foreach my $d (qw/VIDEO_DIR VIDEO_TRASH AUDIO_DIR PVR_LOGDIR PVR_HOME/)
{
my $dir = $settings_href->{$d} ;
if (! -d $dir)
{
print " * $dir .. ($settings_href->{'PVR_USER'}:$settings_href->{'PVR_GROUP'})\n" ;
if (!mkpath([$dir], 0, 0755))
{
print "ERROR unable to create dir $dir : $!" ;
exit 1 ;
}
chown $pvr_uid, $pvr_gid, $dir ;
}
}
# ## Subdirs
# my $dir = "VIDEO_DIR" ;
# foreach my $d (qw/TRASH/)
# {
# my $dir = "$settings_href->{$dir}/$d" ;
# if (! -d $dir)
# {
# print " * $dir .. ($settings_href->{'PVR_USER'}:$settings_href->{'PVR_GROUP'})\n" ;
# if (!mkpath([$dir], 0, 0755))
# {
# print "ERROR unable to create dir $dir : $!" ;
# exit 1 ;
# }
# chown $pvr_uid, $pvr_gid, $dir ;
# }
#
# }
# pvr server
foreach my $dir (qw%/var/run/quartzpvr%)
{
if (! -d $dir)
{
print " * $dir .. ($settings_href->{'PVR_USER'}:$settings_href->{'PVR_GROUP'})\n" ;
if (!mkpath([$dir], 0, 0755))
{
print "ERROR unable to create dir $dir : $!" ;
exit 1 ;
}
chown $pvr_uid, $pvr_gid, $dir ;
}
}
}
#----------------------------------------------------------------------
# Install
#
sub install_files
{
my ($app, $settings_href, $dirs_aref) = @_ ;
my $dest = $settings_href->{'PVR_ROOT'} ;
print "Installing files:\n" ;
foreach my $aref (@$dirs_aref)
{
my ($dir, $owner) = @$aref ;
## copy directory
print " * Installing files from $dir .. " ;
runit($app,
"cp -pr $dir $dest",
"copying files from $dir"
) ;
print "done\n" ;
# $app->run("cp -pr $dir $dest") ;
# print "done\n" ;
# my $status = $app->run()->status ;
# if ($status)
# {
# print "Error copying files from $dir\n" ;
# exit 1 ;
# }
## Set ownership
runit($app,
"chown -R $owner $dest/$dir",
"setting ownership of $dest/$dir to $owner"
) ;
# $app->run("chown -R $owner $dest/$dir") ;
# $status = $app->run()->status ;
# if ($status)
# {
# print "Error setting ownership of $dest/$dir to $owner\n" ;
# exit 1 ;
# }
}
## Copy index file
runit($app,
"cp index.php $dest",
"copying index.php to $dest"
) ;
}
#----------------------------------------------------------------------
# Templates
#
sub template_files
{
my ($app, $settings_href, $template_file) = @_ ;
my %vars = (%$settings_href) ;
$vars{'uid'} = $< ;
$vars{'gid'} = $( ;
$vars{'web_uid'} = getpwnam($settings_href->{'WEB_USER'}) ;
$vars{'web_gid'} = getgrnam($settings_href->{'WEB_GROUP'}) ;
$vars{'pvr_uid'} = getpwnam($settings_href->{'PVR_USER'}) ;
$vars{'pvr_gid'} = getgrnam($settings_href->{'PVR_GROUP'}) ;
$vars{'pvrdir'} = $settings_href->{'PVR_ROOT'} ;
foreach my $field (keys %$settings_href)
{
$vars{lc $field} = $settings_href->{$field} ;
}
$app->prt_data("template_files() : vars=", \%vars) if $DEBUG >= 2 ;
## read in control file
my @templates ;
my $line ;
open my $fh, "<$template_file" or die "Error: Unable to read template control file $template_file : $!" ;
while (defined($line=<$fh>))
{
chomp $line ;
next if $line =~ m/^\s*#/ ;
# "php/Config/Constants.inc", "$pvrdir/php/Config/Constants.inc", $web_uid, $web_gid, 0666
my @fields = split(/,/, $line) ;
if (@fields >= 5)
{
my $aref = [] ;
foreach my $field (@fields)
{
$field =~ s/^\s+// ;
$field =~ s/\s+// ;
$field =~ s/^['"](.*)['"]$/$1/ ;
# $field =~ s/\$(\w+)/$vars{$1}/ge ;
$field =~ s/\$(\w+)/$vars{$1}/g ;
push @$aref, $field ;
}
push @templates, $aref ;
}
}
close $fh ;
$app->prt_data("templates=", \@templates) if $DEBUG >= 2 ;
## Process template files
print "Installing template files:\n" ;
foreach my $aref (@templates)
{
my ($src, $dest, $uid, $gid, $mode) = @$aref ;
$mode = oct($mode) ;
print " * Installing template $src .. " ;
# read
local $/ ;
open my $fh, "<$src" or die "Error: unable to read template $src : $!" ;
my $data = <$fh> ;
close $fh ;
# translate
# $data =~ s/\%([\w_]+)\%/$settings_href->{$1}/ge ;
$data =~ s/\%([\w_]+)\%/$settings_href->{$1}/g ;
# check destination directory
my $dir = dirname($dest) ;
if (! -d $dir)
{
mkpath([$dir], 0, 0755) ;
chown $uid, $gid, $dir ;
}
# write
open my $fh, ">$dest" or die "Error: unable to write template $dest : $!" ;
print $fh $data ;
close $fh ;
# set perms
chown $uid, $gid, $dest ;
chmod $mode, $dest ;
print "\nSet $dest owner $uid:$gid mode $mode\n" if $DEBUG ;
print "done\n" ;
}
}
#----------------------------------------------------------------------
sub start_server
{
my ($app, $settings_href) = @_ ;
print "Starting QuartzPVR server ..\n" ;
system("/etc/init.d/quartzpvr-server restart") ;
print "Setting QuartzPVR server service runlevels ..\n" ;
my $rc ;
$rc = try_runit($app, "chkconfig quartzpvr-server on") ;
print " * Success (chkconfig)\n" if ($rc == 0) ;
$rc = try_runit($app, "update-rc.d quartzpvr-server defaults") ;
print " * Success (update-rc.d)\n" if ($rc == 0) ;
}
#----------------------------------------------------------------------
sub dvbt_scan
{
my ($app, $settings_href) = @_ ;
print "Initialising DVB-T ..\n" ;
## Create dvb
my $dvb = Linux::DVB::DVBT->new('errmode' => 'return') ;
my @devices = $dvb->devices() ;
if (@devices < 1)
{
print " ** No DVB adapters found, skipping **\n" ;
return 0 ;
}
else
{
my $tuning_href = $dvb->get_tuning_info() ;
#Linux::DVB::DVBT::prt_data("Current tuning info=", $tuning_href) ;
$dvb = undef ;
if ($tuning_href)
{
print " * DVB-T already initialised, skipping\n" ;
}
else
{
print " * Tuning DVB-T, this may take some time - please wait ..\n" ;
system("dvbt-scan $settings_href->{'DVBT_FREQFILE'}") ;
}
}
return 1 ;
}
#----------------------------------------------------------------------
sub dvbt_channels
{
my ($app, $settings_href) = @_ ;
print "Updating DVB-T channels ..\n" ;
# $app->run("dvbt-chans-sql ")
runit($app,
"dvbt-chans-sql",
"failed to set up channels table"
) ;
}
#----------------------------------------------------------------------
sub dvbt_listings
{
my ($app, $settings_href) = @_ ;
## Check for listings
my $temp0 = "tmp0-$$.sql" ;
open my $fh, ">$temp0" or die "Error: Unable to create temp file : $!" ;
print $fh <<SQL ;
SELECT * from $settings_href->{DATABASE}.listings LIMIT 1 ;
SQL
close $fh ;
my $results_aref = runit($app,
"mysql -uroot -p$settings_href->{SQL_ROOT_PASSWORD} < $temp0",
"MySQL error while checking for listings"
) ;
# $app->run("mysql -uroot -p$settings_href->{SQL_ROOT_PASSWORD} < $temp0") ;
# my $results_aref = $app->run()->results ;
# my $status = $app->run()->status ;
# if ($status)
# {
# print "Error: MySQL error while loading $temp0\n" ;
# foreach (@$results_aref)
# {
# print "$_\n" ;
# }
# exit 1 ;
# }
my $got_listings = 0 ;
if (@$results_aref)
{
$got_listings = 1 ;
}
if ($got_listings)
{
print "Already got DVB-T listings, skipping\n" ;
}
else
{
print "Gathering DVB-T listings (please wait, this can take 30 minutes or so) ..\n" ;
system("dvbt-epg-sql") ;
}
unlink $temp0 ;
}
#=================================================================================
# FUNCTIONS
#=================================================================================
#----------------------------------------------------------------------
sub get_config
{
my ($app) = @_ ;
my @config = $app->data('config') ;
my %settings ;
foreach my $line (@config)
{
if ($line =~ m/^\s*([\w_]+)\s*=\s*(.*)/)
{
my ($var, $val) = ($1, $2) ;
$val =~ s/\s+$// ;
# replace % place-holder with $
$val =~ s/%/\$/g ;
$settings{$var} = $val ;
}
}
return %settings ;
}
#----------------------------------------------------------------------
# run command
#
sub try_runit
{
my ($app, $cmd) = @_ ;
print STDERR "Run cmd: $cmd\n" if $DEBUG ;
$app->run(
'cmd' => $cmd,
'on_error' => 'status',
) ;
my $results_aref = $app->run()->results ;
my $status = $app->run()->status ;
if ($DEBUG)
{
print STDERR "Status: $status\n" ;
if ($status)
{
print STDERR "Output:\n" ;
foreach (@$results_aref)
{
print STDERR " * $_\n" ;
}
}
}
return wantarray ? ($results_aref, $status) : $status ;
}
#----------------------------------------------------------------------
# run command
#
sub runit
{
my ($app, $cmd, $errmsg) = @_ ;
my ($results_aref, $status) = try_runit($app, $cmd) ;
if ($status)
{
print "Error: $errmsg\n" ;
foreach (@$results_aref)
{
print STDERR "$_\n" ;
}
exit 1 ;
}
return $results_aref ;
}
#----------------------------------------------------------------------
# run mysql command
#
sub mysql_try_runit
{
my ($app, $password, $sql) = @_ ;
print STDERR "Mysql try run cmd: sql=$sql\n" if $DEBUG ;
my $temp0 = "tmp0-$$.sql" ;
open my $fh, ">$temp0" or die "Error: Unable to create temp file : $!" ;
print $fh "$sql\n" ;
close $fh ;
my ($results_aref, $status) = try_runit($app,
"mysql -uroot -p$password < $temp0"
) ;
unlink $temp0 ;
return wantarray ? ($results_aref, $status) : $status ;
}
#----------------------------------------------------------------------
# run mysql command
#
sub mysql_runit
{
my ($app, $password, $sql, $errmsg) = @_ ;
print STDERR "Mysql run cmd: sql=$sql\n" if $DEBUG ;
my $temp0 = "tmp0-$$.sql" ;
open my $fh, ">$temp0" or die "Error: Unable to create temp file : $!" ;
print $fh "$sql\n" ;
close $fh ;
my $results_aref = runit($app,
"mysql -uroot -p$password < $temp0",
$errmsg
) ;
unlink $temp0 ;
return $results_aref ;
}
#=================================================================================
# SETUP
#=================================================================================
__DATA__
[SUMMARY]
Installs the Quartz PVR
[OPTIONS]
-perl_lib=s Perl library path
Set to the Perl library path where the pure perl modules will be installed
-perl_scripts=s Perl script path
Set to the Perl script path where the perl scripts will be installed
-pm_version=s Perl module version
Set to the current version of the Perl module
__DATA__ sql
USE `%DATABASE%`;
--
-- Table structure for table `channels`
--
DROP TABLE IF EXISTS `channels`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `channels` (
`channel` varchar(256) NOT NULL COMMENT 'Channel name used by DVB-T',
`display_name` varchar(256) NOT NULL COMMENT 'Displayed channel name',
`chan_num` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Channel number',
`chan_type` set('tv','radio','hd-tv') NOT NULL DEFAULT 'tv' COMMENT 'TV or Radio',
`show` tinyint(1) NOT NULL DEFAULT '1' COMMENT 'Whether to show this channel or not',
`iplay` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'Can the channel be recorded using get_iplayer',
PRIMARY KEY (`chan_num`),
KEY `type_show_num` (`chan_type`,`show`,`chan_num`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `iplay`
--
DROP TABLE IF EXISTS `iplay`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `iplay` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rid` int(11) NOT NULL,
`pid` varchar(128) NOT NULL COMMENT 'This is a pseduo PID (it''s got the correct date but may not relate to a real program)',
`prog_pid` varchar(128) NOT NULL COMMENT 'This is a real (valid) program pid',
`channel` varchar(128) NOT NULL,
`record` int(11) NOT NULL,
`date` date DEFAULT NULL,
`start` time DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `listings`
--
DROP TABLE IF EXISTS `listings`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `listings` (
`pid` varchar(128) NOT NULL,
`event` int(32) NOT NULL DEFAULT '-1',
`title` varchar(128) NOT NULL,
`date` date NOT NULL,
`start` time NOT NULL,
`duration` time NOT NULL,
`episode` int(11) NOT NULL DEFAULT '0',
`num_episodes` int(11) NOT NULL DEFAULT '0',
`text` longtext NOT NULL,
`channel` varchar(128) NOT NULL,
`genre` varchar(256) DEFAULT '',
`tva_prog` varchar(255) NOT NULL DEFAULT '-' COMMENT 'TV Anytime program id',
`tva_series` varchar(255) NOT NULL DEFAULT '-' COMMENT 'TV Anytime series id',
`audio` enum('unknown','mono','stereo','dual-mono','multi','surround') NOT NULL DEFAULT 'unknown' COMMENT 'audio channels',
`video` enum('unknown','4:3','16:9','HDTV') NOT NULL DEFAULT 'unknown' COMMENT 'video screen size',
`subtitles` tinyint(1) NOT NULL DEFAULT '0' COMMENT 'subtitles available?',
KEY `pid` (`pid`),
KEY `chan_date_start_duration` (`channel`,`date`,`start`,`duration`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `multirec`
--
DROP TABLE IF EXISTS `multirec`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `multirec` (
`multid` int(16) NOT NULL DEFAULT '0' COMMENT 'ID of multiplex recording group ; 0 = no group',
`date` date DEFAULT '2001-01-00',
`start` time DEFAULT '00:00:00',
`duration` time NOT NULL DEFAULT '00:01:00',
`adapter` VARCHAR(16) NOT NULL DEFAULT '0',
KEY `multid` (`multid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `record`
--
DROP TABLE IF EXISTS `record`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` varchar(128) NOT NULL,
`title` varchar(128) NOT NULL,
`date` date NOT NULL,
`start` time NOT NULL,
`duration` time NOT NULL,
`channel` varchar(128) NOT NULL,
`chan_type` varchar(256) DEFAULT 'tv',
`record` int(11) NOT NULL COMMENT '[0=no record; 1=once; 2=weekly; 3=daily; 4=all(this channel); 5=all, 6=series] + [DVBT=0, FUZZY=0x20 (32), DVBT+IPLAY=0xC0 (192), IPLAY=0xE0 (224)] ',
`priority` int(11) NOT NULL DEFAULT '50' COMMENT 'Set priority of recording: 1 is highest; 100 is lowest',
`tva_series` varchar(255) NOT NULL DEFAULT '-',
`tva_prog` varchar(255) NOT NULL DEFAULT '-' COMMENT 'TV Anytime program id',
`pathspec` varchar(255) NOT NULL DEFAULT '' COMMENT 'Path specification: varoables are replaced for each recording',
PRIMARY KEY (`id`),
KEY `pid` (`pid`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `recorded`
--
DROP TABLE IF EXISTS `recorded`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `recorded` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` varchar(128) NOT NULL,
`rid` int(11) NOT NULL COMMENT 'Record ID',
`ipid` varchar(128) NOT NULL DEFAULT '-' COMMENT 'IPLAY: The IPLAYER id (e.g. b00r4wrl)',
`rectype` enum('dvbt','iplay') NOT NULL COMMENT 'Recording type',
`title` varchar(128) NOT NULL,
`text` varchar(255) NOT NULL DEFAULT '',
`date` date NOT NULL,
`start` time NOT NULL,
`duration` time NOT NULL,
`channel` varchar(128) NOT NULL,
`adapter` VARCHAR(16) NOT NULL DEFAULT '0' COMMENT 'DVB adapter number',
`type` enum('tv','radio') NOT NULL DEFAULT 'tv' COMMENT 'Type of recording',
`record` int(11) NOT NULL COMMENT '[0=no record; 1=once; 2=weekly; 3=daily; 4=all(this channel); 5=all, 6=series] + [DVBT=0, FUZZY=0x20 (32), DVBT+IPLAY=0xC0 (192), IPLAY=0xE0 (224)] ',
`priority` int(11) NOT NULL COMMENT 'Set priority of recording: 1 is highest; 100 is lowest',
`genre` varchar(255) NOT NULL DEFAULT '',
`tva_prog` varchar(255) NOT NULL DEFAULT '' COMMENT 'TV Anytime program id',
`tva_series` varchar(255) NOT NULL DEFAULT '' COMMENT 'TV Anytime series id',
`file` varchar(255) NOT NULL COMMENT 'Recorded filename',
`changed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Last modification date/time',
`status` set('started','recorded','error','repaired','mp3tag','split','complete') NOT NULL DEFAULT '' COMMENT 'State of recording',
`statErrors` int(11) NOT NULL DEFAULT '0' COMMENT 'Recording error count',
`statOverflows` int(11) NOT NULL DEFAULT '0' COMMENT 'Recording overflow count',
`statTimeslipStart` int(11) NOT NULL DEFAULT '0' COMMENT 'Seconds timeslipped start of recording',
`statTimeslipEnd` int(11) NOT NULL DEFAULT '0' COMMENT 'Seconds timeslipped recordign end',
`errorText` varchar(255) NOT NULL DEFAULT '' COMMENT 'Summary of any errors',
PRIMARY KEY (`id`),
KEY `pid` (`pid`),
KEY `pid_rectype` (`pid`,`rectype`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `schedule`
--
DROP TABLE IF EXISTS `schedule`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `schedule` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rid` int(11) NOT NULL,
`pid` varchar(128) NOT NULL,
`channel` varchar(128) NOT NULL,
`record` int(11) NOT NULL,
`date` date DEFAULT NULL COMMENT 'DEBUG ONLY!',
`start` time DEFAULT NULL COMMENT 'DEBUG ONLY!',
`priority` int(11) NOT NULL DEFAULT '10' COMMENT 'Lower numbers are higher priority',
`adapter` VARCHAR(16) NOT NULL DEFAULT '0',
`multid` varchar(128) NOT NULL DEFAULT '0' COMMENT 'ID of multiplex recording group ; 0 = no group',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;
__DATA__ versions.sql
USE `%DATABASE%`;
DROP TABLE IF EXISTS `versions`;
CREATE TABLE `versions` (
`id` INT( 8 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`item` VARCHAR( 255 ) NOT NULL ,
`version` VARCHAR( 16 ) NOT NULL
) ENGINE = MYISAM ;
__DATA__ config