#!/usr/bin/perl
#
# tvm2xml.pl
#
# Converts epg-data from different sources to xmltv
#
# This software is released under the GNU GPL
#
# Version 0.2
# - fixed: title,subtitle,description not initiliased
# Version 0.3
# - fixed: missing special charakters in description
# Version 0.4
# - update: compatibility to tvm2vdr 0.5.12
# Version 0.5
# - update: compatibility to tvm2vdr 0.5.14
#
# ToDo: fix malformed utf-8 problem

use IO::Socket;
use Getopt::Std;
use Date::Manip;
use Date::Format;
use HTML::Entities qw(encode_entities_numeric);
use DBI;
&Date_Init("Language=German","DateFormat=non-US");

push (@INC, "./config");
require ("config.pl");
require ("channels.pl");
require ("channels_wanted.pl");

push (@INC, "./inc");
require ("helperfunc");

#---------------------------------------------------------------------------
# main

my $Usage = qq{
Usage: $0 [options]

Options: -s server             mysql server (default: localhost)
         -d database           mysql database (default: mythconverg)
         -u username           mysql username (default: mythtv)
         -p password           mysql password (default: mythtv)
         -i sourceid           Video Source id (default: 1)
         -v                    Show verbose messages
};

die $Usage if (!getopts('h:d:u:p:i:vs') || $opt_h);

our $verbose = $opt_v || 0;
our $sourceid = $opt_i || 1;

our $db_server   = $opt_s  || "localhost";
our $db_database = $opt_d  || "mythconverg";
our $db_user     = $opt_u  || "mythtv";
our $db_pass     = $opt_p  || "mythtv";

$heute   = UnixDate("heute", "%Y%m%d");
$gestern = UnixDate("gestern", "%Y%m%d");

if ($cleanupoldfiles) {
	print "cleanup old files ..\n";
	cleanup();
}

require ("tvmoviefetch");
require ("hoerzufetch");
require ("tvinfofetch");
require ("infosatfetch");
require ("premierefetch");
require ("tvtodayfetch");

if (! -w $imagepath and $writeimages) {
  die "cannot write to $imagepath!\n";
  }

if (! -w $downloadprefix) {
  die "cannot write to $downloadprefix!\n";
  }

if (! -w $updateprefix) {
  die "cannot write to $updateprefix!\n";
  }

if ($writeimages) {
  eval 'use Image::Magick';
  our $ckimage = Image::Magick->new;
  }


$SIG{'INT'}  = \&SIGhandler;


print "reading channels ..\n";

#our $dbh = DBI->connect('DBI:mysql:'.$db_database.":".$db_server,$db_user,$db_pass,{ RaiseError => 1 })
#      or die "Fehler beim Verbinden mit Datenbank : $DBI::errstr\n";
#my @channels = ReadChannelsmyth($sourceid);
our $EXIT = false;
our %XML;

foreach $sender (keys(%chan_wanted)) {
    # print STDERR $sender, "\n";
    if ($chan_wanted{$sender} eq "1") {
        print STDERR "Reading TVMovie for ", $sender, "\n";
        ReadExternalEPG_tvmovie();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "2") {
        ReadExternalEPG_tvinfo();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "3") {
        ReadExternalEPG_hoerzu(); 
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
    if ($chan_wanted{$sender} eq "4") {
        ReadExternalEPG_infosat();
        last;
    }
}

foreach $sender (keys(%chan_wanted)) {
	if ($chan_wanted{$sender} eq "5") {
	        singlesvdrp("mesg getting EPG from premiere ..") unless ($novdr or !$wantosd);
		ReadExternalEPG_premiere();
		last;
	}
}

foreach $sender (keys(%chan_wanted)) {
	if ($chan_wanted{$sender} eq "6") {
	        singlesvdrp("mesg getting EPG from tvtoday ..") unless ($novdr or !$wantosd);
		ReadExternalEPG_tvtoday();
		last;
	}
}

open(EPGFILE," >$epgfile") || die "cannot write epgfile $epgfile : $!";


# EPG & XML-Infos sind beide sortiert im Speicher - jetzt vergleichen.
my $chancounter = 0;
my $chancounts=0;
foreach $sender (keys(%chan)) {
	next if $chan_wanted{$sender} == "0";
	$chancounts++;
	}
    
WriteEPG("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
WriteEPG("<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n");
WriteEPG("<tv>\n"); 
foreach $sender (keys(%chan)) {
	next if $chan_wanted{$sender} == "0";
	
    
    $xmlcount = $#{$XML{$sender}};      # Anzahl XML-Einträge für diesen Sender

    # EPG-Sendername suchen
    my $found=0;
    for my $channel (@channels) {
        if ($channel->{xmltvid} eq $chan{$sender}[0]) {
            $sendername = $channel->{name};
            $found=1;
            print "EPG-Info for $sender:  $#{$XML{$sender}}\n";
            last;
        }
    }

    if ($found eq 0) {
        $sendername = $sender;
        print "\n\n!!!WARNING!!! $sender configured for fetching EPG,\n";
        print "but ".$chan{$sender}[0]." not found in channels.conf!\n";
        print "Please use contrib/printchannels.pl to sync channels.pl!!\n\n";
    }

      
    
    $i=0;
    WriteEPG("\t<channel id=\"$chan{$sender}[0]\">\n\t<display-name lang=\"de\">$sendername</display-name>\n\t</channel>\n");
    doexit() if $please_exit;
          
    for ($i=0; $i<=$xmlcount ;$i++) {
        doexit() if $please_exit;
        $found_orig_event = 0;
        $tline = "";
        $sline = "";
        $dline = "";
        if ($i <= $xmlcount && @{$XML{$sender}}[$i]->{state} > 0) {
            $eline = "@{$XML{$sender}}[$i]->{event_id} @{$XML{$sender}}[$i]->{start} @{$XML{$sender}}[$i]->{duration} 0";
            $unixstart=time2str("%Y%m%d%H%M%S", "@{$XML{$sender}}[$i]->{start}");
            $unixstop=time2str("%Y%m%d%H%M%S", "@{$XML{$sender}}[$i]->{stop}");
            $length = "@{$XML{$sender}}[$i]->{duration}";
            $tline  = "@{$XML{$sender}}[$i]->{title}";
            $sline  = "@{$XML{$sender}}[$i]->{subtitle}";
            $dline  = "@{$XML{$sender}}[$i]->{summary}";
			$vline  = "@{$XML{$sender}}[$i]->{vpsstart}";
        }
        if ( $tline ne "" ){
            WriteEPG("\t<programme start=\"$unixstart +0100\" stop=\"$unixstop +0100\" channel=\"$chan{$sender}[0]\">\n");
            # workaround for encode_entities problem
            $tline =~ s/&/&amp;/g;
            WriteEPG("\t\t<title lang=\"de\">$tline</title>");
            # workaround for encode_entities problem
            $sline =~ s/&/&amp;/g;
            WriteEPG("\t\t<sub-title lang=\"de\">$sline</sub-title>") if ($sline ne "");
            ($category,$special,$flags,@desc) = split ( /\|/, encode_entities_numeric($dline) );
            $credits = "";
            $desc = "";
            foreach $field ( @desc ){
                $field =~ s/[ |\t]+$//g;
                if ( $field =~ s/Category:[ \?]+// ){
                    WriteEPG("\t\t<category lang=\"de\">$field</category>\n");
                }elsif ( $field =~ s/Genre:[ \?]+// ){
                    WriteEPG("\t\t<genre lang=\"de\">$field</genre>\n");
                }elsif ( $field =~ s/Originaltitle:[ \?]+// ){
                    WriteEPG("\t\t<title lang=\"en\">$field</title>");
                }elsif ( $field =~ s/Country:[ \?]+// ){
                    WriteEPG("\t\t<country lang=\"de\">$field</country>\n");
                }elsif ( $field =~ s/Year:[ \?]+// ){
                    WriteEPG("\t\t<date lang=\"de\">$field</date>\n");
                }elsif ( $field =~ s/Episode:[ \?]+// ){
                    WriteEPG("\t\t<episode-num>$field</episode-num>\n");
                }elsif ( $field =~ s/Format:[ \?]+// ){
                    WriteEPG("\t\t<video>\n\t\t<aspect>$field</aspect>\n\t\t</video>\n");
                }elsif ( $field =~ s/Cast:[ \?]+// ){
                    @actors = split( /, /, $field);
                    foreach $actor ( @actors ){
                        $actor =~ s/[ ,]+$//g;
                        $credits .= "\t\t<actor>$actor</actor>\n";
                    }
                }elsif ( $field =~ s/Director:[ \?]+// ){
                    @directors = split( /, /, $field);
                    foreach $director ( @directors ){
                        $director =~ s/[ ,]+$//g;
                        $credits .= "\t\t<director>$director</director>\n";
                    }
                }elsif ( $field =~ s/Audio:[ \?]+// ){
                    WriteEPG("\t\t<audio>\n\t\t<stereo>$field</stereo>\n\t\t</audio>\n");
                }elsif ( $field =~ s/FSK:[ \?]+// ){
                    WriteEPG("\t\t<rating system =\"FSK\">\n\t\t<value>$field</value>\n\t\t</rating>\n");
                }else{
                    $field =~ s/[^a-zA-Z0-9,.!?;]+$//;
                    $desc .= $field;
                }
                
            }
            WriteEPG("\t\t<credits>\n$credits\t\t</credits>") if ($credits ne "");
            WriteEPG("\t\t<desc lang=\"de\">$desc</desc>") if ($desc ne "");
            WriteEPG("\t</programme>\n");
        }
    }
}
WriteEPG("</tv>\n");

close EPGFILE;

exit;




sub WriteEPG {
my $line = pack "U0C*", unpack "C*", shift;
    use bytes;
    print EPGFILE $line;
    print EPGFILE "\n";
    no bytes;
}

sub ReadChannelsmyth {
   $sourceid = shift;
   $query = "select name,xmltvid from channel where xmltvid != '' and sourceid=$sourceid;";
   $sth = $dbh->prepare( $query );
   $sth->execute();
   while(my ($name,$xmltvid) = $sth->fetchrow_array()){
       ($id,$provider) = split("-", $xmltvid);
       $rfc2838 = "";
       foreach $sender (keys(%chan)) {
           if ($chan{$sender}[0] eq $xmltvid) {
           $rfc2838 = $sender;
           last;
           }
       }
       next if $rfc2838 eq "";

       $chan_wanted{$rfc2838} = $provider;
       push(@chan, {
            name         => $name,
            xmltvid      => $xmltvid,
            rfc2838      => $rfc2838
            });
  }
  return(@chan);
}

sub Error
{
  print STDERR "Fehler: @_\n";
  close(SOCK);
  exit 0;
}


