#!/usr/bin/perl -w
#
# Copyright G. Westcott - February 2013
#
# This code is distributed under the GNU General Public License v2 (GPLv2) .
#
#   For extended help information run
#         tv_grab_uk_tvguide  --info
#

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
    if 0; # not running under some shell

use Data::Dumper;

use strict;
use warnings;
use XMLTV 1.0.1;
use XMLTV::ProgressBar;
use XMLTV::Options qw/ParseOptions/;
use XMLTV::Configure::Writer;
use XMLTV::Supplement 0.005065 qw/SetSupplementRoot GetSupplementDir GetSupplementLines/;
use XMLTV::Get_nice 0.005065 qw/get_nice_tree/;

use File::Path;
use POSIX qw(strftime);
use DateTime;
use Date::Parse;
#v1.3: use DateTime::Format::DateParse;
use Encode;
use URI::Escape;
use LWP::UserAgent;
use HTTP::Cookies;
use HTML::TreeBuilder;
use HTTP::Cache::Transparent;


#require HTTP::Cookies;
#my $cookies = HTTP::Cookies->new;
#$XMLTV::Get_nice::ua->cookie_jar($cookies);


# Although we use HTTP::Cache::Transparent, this undocumented --cache
# option for debugging is still useful since it will _always_ use a
# cached copy of a page, without contacting the server at all.
#
use XMLTV::Memoize; XMLTV::Memoize::check_argv('XMLTV::Get_nice::get_nice_aux');

use subs qw(debug warning);
my $warnings = 0;


use XMLTV::Usage <<END;
tv_grab_uk_tvguide: Get UK television listings in XMLTV format
Version: $XMLTV::VERSION
To configure: $0 --configure [--config-file FILE] [--gui OPTION]
To grab listings: $0 [--config-file FILE] [--output FILE] [--quiet] [--offset DAYS] [--days DAYS] [--nodetailspage] [--legacychannels]
To list available channels: $0 --list-channels [--output FILE]
END


# ------------------------------------------------------------------------------------------------------------------------------------- #
# Grabber details
my $VERSION				= "$XMLTV::VERSION";
my $GRABBER_NAME		= 'tv_grab_uk_tvguide';
my $GRABBER_DESC		= 'UK - TV Guide (tvguide.co.uk)';
my $GRABBER_URL			= 'http://wiki.xmltv.org/index.php/XMLTVProject';
my $ROOT_URL			= 'https://www.tvguide.co.uk/';
my $SOURCE_NAME			= 'TV Guide UK';
my $SOURCE_URL			= 'https://www.tvguide.co.uk/';
#
my $generator_info_name	= $GRABBER_NAME;
my $generator_info_url	= $GRABBER_URL;
my $source_info_name	= $SOURCE_NAME;
my $source_info_url		= $SOURCE_URL;
#
my $grabberid = '2023-02-17.1139';

# ------------------------------------------------------------------------------------------------------------------------------------- #
# Use XMLTV::Options::ParseOptions to parse the options and take care of the basic capabilities that a tv_grabber should have

our ($opt, $conf) = ParseOptions({
			grabber_name		=> $GRABBER_NAME,
			capabilities		=> [qw/baseline manualconfig apiconfig cache tkconfig/],		# apiconfig is needed for --list-channels (bug)
			stage_sub			=> \&config_stage,
			listchannels_sub	=> \&fetch_channels,
			version				=> $VERSION,
			description			=> $GRABBER_DESC,
			extra_options		=> [qw/nodetailspage legacychannels method:i makeignorelist:s useignorelist:s usage test:i/],
});
 
usage(1) if $opt->{usage};

#print Dumper($conf); exit;

# any overrides?
if (defined( $conf->{'generator-info-name'} ))	{ $generator_info_name 	= $conf->{'generator-info-name'}->[0]; }
if (defined( $conf->{'generator-info-url'} ))	{ $generator_info_url  	= $conf->{'generator-info-url'}->[0]; }
if (defined( $conf->{'source-info-name'} )) 	{ $source_info_name 	= $conf->{'source-info-name'}->[0]; }
if (defined( $conf->{'source-info-url'} ))  	{ $source_info_url  	= $conf->{'source-info-url'}->[0]; }


# initialise the gui
XMLTV::Ask::init($opt->{gui});


# ------------------------------------------------------------------------------------------------------------------------------------- #
# Initialise the web page cache
init_cachedir( $conf->{cachedir}->[0] );
HTTP::Cache::Transparent::init( {
	BasePath => $conf->{cachedir}->[0],
	NoUpdate => 60*60,			# cache time in seconds
	MaxAge => 24,				# flush time in hours
	Verbose => $opt->{debug},
} );


# ------------------------------------------------------------------------------------------------------------------------------------- #
# Check we have all our required conf params
config_check();

# Load the conf file containing mapped channels and categories information
my %mapchannelhash;
my %mapcategoryhash;
loadmapconf();
#print Dumper(\%mapchannelhash, \%mapcategoryhash); exit;



# ------------------------------------------------------------------------------------------------------------------------------------- #
# Progress Bar :)
my $bar = new XMLTV::ProgressBar({
		name => "Fetching listings",
		count => (scalar @{$conf->{channel}}) * ($opt->{days} + 1)		# +1 added for the extra day necessary for <06:00 programmes
}) unless ($opt->{quiet} || $opt->{debug});



# ------------------------------------------------------------------------------------------------------------------------------------- #
# Data store before being written as XML
my $programmes = ();
my $channels = ();

# Store channel names during fetch
my $channames = undef;

# Get the schedule(s) from TV Guide
fetch_listings();

# print Dumper($programmes);

# Progress Bar
$bar->finish() && undef $bar if defined $bar;



# ------------------------------------------------------------------------------------------------------------------------------------- #
# Filter out programmes outside of requested period (see man page)
my %w_args;
if (($opt->{offset} != 0) || ($opt->{days} != -999)) {
	$w_args{offset} = $opt->{offset};
	$w_args{days}   = ($opt->{days} == -999) ? 100 : $opt->{days};
	$w_args{cutoff} = '000000';			# e.g. '060000'
}



# ------------------------------------------------------------------------------------------------------------------------------------- #
# Generate the XML
my $encoding = 'UTF-8';
my $credits = { 'generator-info-name' 	=> $generator_info_name,
				'generator-info-url' 	=> $generator_info_url,
				'source-info-name' 		=> $source_info_name,
				'source-info-url' 		=> $source_info_url };

XMLTV::write_data([ $encoding, $credits, $channels, $programmes ], %w_args);
# Finished!



# ------------------------------------------------------------------------------------------------------------------------------------- #
# Signal that something went wrong if there were warnings.
exit(1) if $warnings;

# All data fetched ok.
debug "Exiting without warnings.";
exit(0);


# #############################################################################
# # THE MEAT #####################################################################
# ------------------------------------------------------------------------------------------------------------------------------------- #

sub fetch_listings {
	# Fetch listings per channel

	foreach my $channel_id (@{$conf->{channel}}) {
		# Officially:
		# http://www.tvguide.co.uk/channellisting.asp?cTime=3%2F19%2F2013+06%3A00%3A00+&ch=857&go=go
		# But this works too:
		# http://www.tvguide.co.uk/channellisting.asp?ch=86&cTime=3/18/2013

		my $baseurl = $ROOT_URL.'channellistings.asp';

		# Now grab listings for each channel on each day, according to the options in $opt
		#
		# tvguide runs from 06:00 so we need to get the previous day as well just for any programmes after midnight
		#
		for (my $i=($opt->{offset} -1); $i < ($opt->{offset} + $opt->{days}); $i++) {
			my $theday = DateTime->today->add (days => $i)->set_time_zone('Europe/London');

			# Construct the listings url
			my $url = $baseurl . '?ch=' . $channel_id . '&cTime=' . uri_escape( $theday->strftime('%m/%d/%Y 00:00:00') );
			#debug "Fetching: $url";

			# If we need to map the fetched channel_id to a different value
			my $xmlchannel_id = $channel_id;
			$xmlchannel_id .= '.tvguide.co.uk' unless $opt->{legacychannels};		# make channel RFC2838 compliant
			if (defined(&map_channel_id)) { $xmlchannel_id = map_channel_id($xmlchannel_id); }

			# Fetch the page
			#   my $tree = XMLTV::Get_nice::get_nice_tree($url);
			my $tree = fetch_url($url);
			# $tree->dump; exit;

			# Scrub the page
			if ($tree) {
				my $channelname = undef;
				
				# Store the channel ids in a list (do this only once per program run)
				if (!defined $channames) {
					#debug 'fetching options tags';
					my $choptions = $tree->look_down('_tag' => 'select', 'name' => 'ch');
					if (defined $choptions) {
						my @choptionslist = $choptions->look_down('_tag' => 'option');
						if (@choptionslist) {
							foreach my $choption (@choptionslist) {
								$channames->{$choption->attr('value')} = $choption->as_text;
							}
						}
					}
				}

				$channelname = $channames->{$channel_id} if $channames;

				# Try a fallback method if the form options are missing [Credit mkbloke]
				if (!defined $channelname) {
					#debug 'using fallback method';
					my $fallback = $tree->look_down('_tag' => 'input', 'name' => 'cTime');
					$fallback = $fallback->look_up('_tag', 'tr') if $fallback;
					$channelname = $fallback->look_down('_tag' => 'span', 'class' => 'programmeheading') if $fallback;
					$channelname = $channelname->as_text if $channelname;
				}

				#debug 'found channel name: '.$channelname;

				# tvguide website can be very slow - try to avoid barfing when no response
				# if no channelname then assume we got no response from website
				if (!defined $channelname) {
					warning "Unable to retrieve web page for $channel_id";
					next;
				}

				# 	<table border="0" cellpadding="0" style="background:black;border-collapse: collapse;background-image: url(http://i.g8.tv/HighlightImages/Large/);background-repeat: no-repeat;" width="677">
				#
				my @shows = $tree->look_down('_tag' => 'table', 'border' => '0', 'cellpadding' => '0', 'style' => q                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           