#!/usr/bin/perl -w
# VERSION: 1.0b2 - myth2ipod
# Get the latest version, and change log at myth2ipod.com
# Author: Chris aka Wififun - email: wififun@myth2ipod.com 
# Contributions and testing by Paul Egli
# modified to use nuvexport by starv at juniks dot org

# Includes
use DBI;
use Getopt::Long;
use File::Path;

# User variables
my $portable = "XviD";
my $feedfile = "/myth/video/archive/feed.php";
my $feedpath = "/myth/video/archive/";
my $wwwloc = "/data/srv/httpd/htdocs";
my $feedurl = "http://REPLACEME/archive/";
my $nuvoptions ="--mode=XviD --nice=19 --cutlist --nodenoise --nodeinterlace --crop --multipass";

# Some variables
our ($dest, $format, $usage);
our ($db_host, $db_user, $db_name, $db_pass, $video_dir);
our ($hostname, $db_handle, $sql, $statement, $row_ref);
our ($chanid, $start, $nuvfile, @nuvarray);	
my $rebuild = '0';
my $encode = '0';
my $debug = '0';
my $setup = '0';
my $cut = '0';
my( $rightnow ) = `date`; 

GetOptions ("rebuild" => \$rebuild,
	    "encode"   => \$encode,
	    "debug"	=>	\$debug,
	    "setup" => \$setup,
	    "cut" => \$cut);

if ($setup == 1){
    system("clear");
    print "Setup will do everything needed to run this script.\n";
    print "This has only been tested on KnoppMyth R5A22.\n";
    print "make sure you have edited the variables for your conguration.\n";
    my $cksetup = &promptUser("\nAre you sure you want to procceed?","n");
    if ($cksetup =~ "y") {
	DoSetup();
	exit;
    }
    print "Setup exited. Nothing done.\n";
    exit;
}
elsif ($rebuild == 1){
    GenerateRSSFeed();
    print "Rebuilding of RSS feed is complete.\n";
    exit;
}
else {
    Encode4Portable();
    print "$title is ready for your $portable\n";
    
    # Check to see if the feed file exists; if not, create it.
    if (! -e $feedfile) { 
	print "No feed file found. I will make one for you.\n";
	GenerateRSSFeed();
	print "All done.\n";
    }
}

sub Encode4Portable{
    if ($#ARGV != 1) { 
	print "Encoding requires options.\nusage: myth2ipod <options> DIRECTORY FILE\n"; 
	exit; 
    }
    
    # Get the show information
    $directory = $ARGV[0]; 
    $file = $ARGV[1]; 
    @file = split(/_/, $file);
    $chanid = $file[0];
    $start = substr $file[1],0,14;
    if($debug == 1){ print "$chanid\n$start\n"};
    if (! -e $directory."/".$file){
	print "Oops, the file ".$directory.$file." does not exist.\n";
	exit;
    }
    
    # Connect to the database
    PrepSQLRead();
    $db_handle = DBI->connect("dbi:mysql:database=$db_name:host=$db_host", $db_user, $db_pass)
	or die "Cannot connect to database: $!\n\n";
    $sql = "SELECT title, subtitle, description, category, starttime FROM recorded WHERE chanid = $chanid AND DATE_FORMAT(starttime,'%Y%m%d%H%i%s') = $start";

    $statement = $db_handle->prepare($sql)
	or die "Couldn't prepare query '$sql': $DBI::errstr\n";
    
    $statement->execute()
	or die "Couldn't execute query '$sql': $DBI::errstr\n";
    $row_ref = $statement->fetchrow_hashref();
    if($debug == 1){ print "$row_ref->{starttime}\n"};
    $title = $row_ref->{title}; 
    $subtitle = $row_ref->{subtitle};
    $recorddate = $row_ref->{starttime}; 
    $description = $row_ref->{description};
    $category = $row_ref->{category};
    $filename = $title."-".$subtitle."-".substr $start, 0, 8;
    $filename =~ s/ /_/g;
    $filename =~ s/&/+/g;
    $filename =~ s/\047//g;
    $filename =~ s/[^+0-9a-zA-Z_-]+/_/g;
    $filename =~ s/_$//g;
    
    printf("Starting nuvexport...\n"); 
    EncodeIt(); 
    printf("Nuvexport completed, starting xml generation...\n"); 
    CreateItemXML(); 
    printf("XML file created for \"$filename\" : Yipeee\n"); 
    printf("Cleaning up temporary files\n"); 
    $cmd = "rm -f $feedpath$chanid\_$start.temp.mp4";
    print $cmd."\n";
    if(system($cmd)) { print "Removing nuvexport temp file failed\n"; }
    
    # remove the cutlist incase we added it.
    if ($cut == 1){
	printf("Generating cutlist\n"); 
	$cmd = "/usr/bin/mythcommflag --chanid $chanid --starttime $start --clearcutlist";
	print $cmd."\n"; 
	if(system($cmd)) { print "It looks like I was not able to generate a cutlist.\n"; } 
    }
    return 0;
}

#
# Encode for Portable
#
sub EncodeIt { 
    # Create cutlist from commercial flagging if -cut was passed to the script
    if ($cut == 1){
	printf("Generating cutlist\n"); 
	$cmd = "/usr/bin/mythcommflag --chanid $chanid --starttime $start --gencutlist";
	print $cmd."\n"; 
	if(system($cmd)) { print "It looks like I was not able to generate a cutlist.\n"; } 
    }
    
    # Use nuvexport to do the work
    $cmd = "/usr/bin/nuvexport --chanid=$chanid --start=$start $nuvoptions --filename=$chanid\_$start.$portable --path=$feedpath";
    print $cmd."\n"; 
    if(system($cmd)) { print "Nuvexport encoding seems to have failed\n"; } 
    
    # Now clean up the output so iPods with firmware 1.1 and above can use it
    #$cmd = "/usr/local/bin/MP4Box -add $feedpath$chanid\_$start.temp.mp4 $feedpath$chanid\_$start.$portable.mp4";
    #print $cmd."\n"; 
    #if(system($cmd)) { print "MP4Box cleanup seems to have failed\n"; } 
    return 0;
}

#
# Create XML with <ITEM> tag for this video file
#
sub CreateItemXML {
    open(ITEM, ">$feedpath$chanid\_$start.$portable.xml");
    print ITEM "<item>\n";  
    print ITEM "<title>".&encodeForXML($title." - ".$subtitle)."</title>\n";
    print ITEM "<itunes:author>MythTV</itunes:author>\n";  
    print ITEM "<author>MythTV</author>\n";  
    print ITEM "<itunes:category text=\"TV Shows\"></itunes:category>\n";
    print ITEM "<comments>".&encodeForXML($file)."</comments>\n";  
    print ITEM "<description>".&encodeForXML($description)."</description>\n";  
    print ITEM "<pubDate>".$recorddate."</pubDate>\n";  
    print ITEM "<enclosure url=\"".&encodeForXML("$feedurl$chanid\_$start.$portable.avi")."\" type=\"video/quicktime\" />\n";  
    print ITEM "<itunes:duration></itunes:duration>\n";  
    print ITEM "<itunes:keywords>".&encodeForXML($title." - ".$subtitle." - ".$category)."</itunes:keywords>\n";
    print ITEM "<category>".&encodeForXML($category)."</category>\n";			
    print ITEM "</item>\n";
    print "\"$filename\" has been added to the feed.\n";
    close(ITEM);
    return 0;
}

#
# Generate the RSS feed by combining the ITEM XML Files
#
sub GenerateRSSFeed {

    open(RSS, ">$feedfile");
    print RSS "<?php\n"; 
    print RSS "header(\"Content-Type: text/xml\");\n"; 
    print RSS "echo \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\"; ?>\n"; 
    print RSS "<rss xmlns:itunes=\"http://www.itunes.com/DTDs/Podcast-1.0.dtd\" version=\"2.0\">\n"; 
    print RSS "<channel>\n"; 
    print RSS "<title>MythTV - <? if (\$_GET['title'] == \"\") { \$title = \"*\"; echo \"Recorded Programs\"; }\n";
    print RSS "else { \$title = \$_GET['title']; echo str_replace(\"_\",\" \",\$_GET['title']); } ?> </title>\n";
    print RSS "<itunes:author>MythTV - myth2ipod</itunes:author>\n"; 
    print RSS "<link>".&encodeForXML($feedurl)."</link>\n";
    print RSS "<itunes:subtitle>Transcoded recording for your iPod Video.</itunes:subtitle>\n"; 
    print RSS "<itunes:summary>Myth TV Recorded Programs for the iPod v.1</itunes:summary>\n"; 
    print RSS "<description>Myth TV Recorded Programs for the iPod v.1</description>\n"; 
    print RSS "<itunes:owner>\n"; 
    print RSS "<itunes:name>MythTV</itunes:name>\n"; 
    print RSS "<itunes:email>mythtv\@localhost</itunes:email>\n"; 
    print RSS "</itunes:owner>\n"; 
    print RSS "<itunes:explicit>No</itunes:explicit>\n"; 
    print RSS "<language>en-us</language>\n"; 
    print RSS "<copyright>Copyright 2005.</copyright>\n"; 
    print RSS "<webMaster>mythtv\@localhost</webMaster>\n"; 
    print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\" />\n"; 
    print RSS "<itunes:category text=\"TV Shows\"></itunes:category>\n"; 
    print RSS "<category>TV Shows</category>\n";
    print RSS "<itunes:image href=\"http://myth2ipod.com/mythipod_200.jpg\"/>";
    print RSS "<image>"; 
    print RSS "<url>http://myth2ipod.com/mythipod_200.jpg</url>\n";
    print RSS "<title>MythTV 2 iPod</title>\n";
    print RSS "<link>".&encodeForXML($feedurl)."</link>\n";	
    print RSS "<width>200</width>\n";		
    print RSS "<height>200</height>\n";		
    print RSS "</image>\n";
    print RSS "<? foreach (glob(\$title\.\"*\.$portable\.xml\") as \$file) {include \$file;} ?>\n";
    print RSS "</channel>\n"; 
    print RSS "</rss>\n";
    close(RSS);
    if($debug == 1){ print "I created a feed file, was I supposed to?\n"};

    return 0;
}

# substitute for XML entities
sub encodeForXML {
    local $result;
    $result = $_[0];
    $result =~ s/&/&amp;/g;
    $result =~ s/</&lt;/g;
    $result =~ s/>/&gt;/g;
    $result;
}


#
# This code taken from one of the mythlink.sh scripts to get MySQL information
#
sub PrepSQLRead{
# Get the hostname of this machine
    $hostname = `hostname`;
    chomp($hostname);
    
# Read the mysql.txt file in use by MythTV.
# could be in a couple places, so try the usual suspects
    my $found = 0;
    my @mysql = ('/usr/local/share/mythtv/mysql.txt',
                 '/usr/share/mythtv/mysql.txt',
                 '/etc/mythtv/mysql.txt',
                 '/usr/local/etc/mythtv/mysql.txt',
                 "$ENV{HOME}/.mythtv/mysql.txt",
                 'mysql.txt'
	);
    foreach my $file (@mysql) {
        next unless (-e $file);
        $found = 1;
        open(CONF, $file) or die "Unable to open $file:  $!\n\n";
        while (my $line = <CONF>) {
	    # Cleanup
            next if ($line =~ /^\s*#/);
            $line =~ s/^str //;
            chomp($line);
	    # Split off the var=val pairs
            my ($var, $val) = split(/\=/, $line, 2);
            next unless ($var && $var =~ /\w/);
            if ($var eq 'DBHostName') {
                $db_host = $val;
            }
            elsif ($var eq 'DBUserName') {
                $db_user = $val;
            }
            elsif ($var eq 'DBName') {
                $db_name = $val;
            }
            elsif ($var eq 'DBPassword') {
                $db_pass = $val;
            }
	    # Hostname override
            elsif ($var eq 'LocalHostName') {
                $hostname = $val;
            }
        }
        close CONF;
    }
    die "Unable to locate mysql.txt:  $!\n\n" unless ($found && $db_host);
    return 0;
}

sub promptUser {
    local($promptString,$defaultValue) = @_;
    if ($defaultValue) {
	print $promptString, "[", $defaultValue, "]: ";
    } else {
	print $promptString, ": ";
    }

    $| = 1;               # force a flush after our print
    $_ = <STDIN>;         # get the input from STDIN (presumably the keyboard)
    chomp;
    if ("$defaultValue") {
	return $_ ? $_ : $defaultValue;    # return $_ if it has a value
    } else {
	return $_;
    }
}

sub DoSetup {
    print "\nNot ready yet. How do you send the cd command from perl?\n";
    return 0;
}
