#!/usr/bin/perl
#
# fetch_one: download TV program data from www.sofcom.com.au/tv and
# convert to a textual form which can be turned into a TiVo slice file. 
#
# Copyright (c) Warren Toomey, wkt@tuhs.org, January 2002.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 0. This software must only be used in those parts of the world which
#    cannot obtain a program subscription service from TiVo, Inc.
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
#    must display the following acknowledgement:
#      This product includes software developed by Warren Toomey.
# 4. Warren Toomey's name may not be used to endorse or promote products
#    derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY WARREN TOOMEY ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL WARREN TOOMEY BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#    $Revision: 1.76 $
#
use strict;

# Exported global variables and functions
#
use Exporter();
use vars qw(@ISA @EXPORT %NumericGenre $HTTP_PROXY $Outputformat
		$is_lastday $is_firstday $do_write_numbers
		%UnknownProgram %StationUrl $Webdir %Stationid %Genre
		$SeriesNum $ProgramNum $StationDayNum $SliceNum
		$Basedir $Websource $Try_again $AskSofcomForGenres
		%Series %Episode %IsEpisodic %TrimTitles %FudgeStart %FudgeEnd);
@ISA         = qw(Exporter);
@EXPORT      = qw(%NumericGenre $HTTP_PROXY $Outputformat
		$is_lastday $is_firstday $do_write_numbers
		%UnknownProgram %StationUrl $Webdir %Stationid %Genre
		$SeriesNum $ProgramNum $StationDayNum $SliceNum
		$Basedir $Websource $Try_again $AskSofcomForGenres
		%Series %Episode %IsEpisodic %TrimTitles %FudgeStart %FudgeEnd);

# Functions used from other files
#
use TiVo::TiVoSlice;
use TiVo::SofcomParser;
use TiVo::ConfigFiles;
use TiVo::SliceMaker;

# Local variables
#
my ($fetch_or_make);
my ($arg_count, $aptr, $ch, $slice_file);

#
# MAIN PROGRAM
#
# Run-time flags: allow saving of URL to file and replay from file.
#
$fetch_or_make="fetch"; $do_write_numbers=1;

while (($#ARGV>-1) && ($ARGV[0] =~ /^-[rwno]/)) {
  if ($ARGV[0] eq "-w") { $fetch_or_make="fetch"; shift; }
  if ($ARGV[0] eq "-r") { $fetch_or_make="make"; shift; }
  if ($ARGV[0] eq "-n") { $do_write_numbers=0;  shift; }
  if ($ARGV[0] eq "-o") { $slice_file=$ARGV[1]; shift; shift; }
}

#
# Check we have pairs of arguments to pass to the do_a_channel_day function
#
$arg_count= $#ARGV + 1;
if (($arg_count<2) || ($arg_count%2)!=0) {
  print("Usage: fetch_one [-r or -w] [-n] [-o output] station day_list ");
  print("[station day_list]\n\n");
  exit(1);
}

# Get the configuration details to find the run-time files and other things
&get_configfile;

# Read in the datafiles for genre, stations and incremental numbers
#
&read_datafiles;

# Initialise the writing of the TiVo slice output
#
if (!defined($slice_file)) {
  print(STDERR "Error: output file must be specified with the -o option\n");
  exit(1);
}
&initialise_slice_output($slice_file);

# Do each channel/day pair described on the command line
#
$is_firstday=1; $is_lastday=0;
for ($aptr=0; $aptr< ($arg_count); $aptr+=2) {
    #
    # Work out if this is the last day we are processing.
    # See further down as to why this is important.
    #
    if (($arg_count - $aptr)==2) { $is_lastday=1; }
    #
    # Do a single station if the station name isn't All
    #
    if ($ARGV[$aptr] ne "All") {
       &do_a_channel_daylist($ARGV[$aptr], $ARGV[$aptr+1]);
    } else {
       #
       # Find all the station names we know, and do them all for
       # the given day offset
       #
       foreach $ch (keys(%StationUrl)) {
          &do_a_channel_daylist($ch, $ARGV[$aptr+1]);
       }
    }
    $is_firstday=0;
}

# We have already printed out the series and programs,
# now print out the showings.
#
&print_showings;

# Write out the changed genre, numbers and episode datafiles
#
&write_datafiles;
&finalise_slice_output;
exit(0);


#######################################################################
#				Subroutines			      #
#######################################################################


# This short procedure simply allows us to decode a list of days
# before we pass to the real do_a_channel_day procedure.
# Note, however, that we have to fix the is_lastday if we have
# been given a daylist, rather than a single day.
sub do_a_channel_daylist {
  my($channel,$wanteday) = @_;
  my($i,$start,$end);

  # Abort if the channel is not known
  #
  if (!defined($StationUrl{$channel})) {
    print(STDERR "Error: station $channel unrecognised, possible values are\n");
    foreach $i (sort(keys(%StationUrl))) { print(STDERR "$i "); }
    print(STDERR "\n"); exit(1);
  }

  if ($wanteday=~ /(\d+)-(\d+)/) {
    $start=$1; $end=$2;
    $is_firstday=1; $is_lastday=0;
    for ($i=$start; $i <= $end; $i++) {
	if ($i == $end) { $is_lastday=1; }
	&do_a_channel_day($channel, $i);
	$is_firstday=0;
    }
  } else { &do_a_channel_day($channel, $wanteday); }
}

# Procedure do_a_channel_day: Work out which particular web fetcher
# and parser to use to do the rest of the work.
#
# PLACE A HOOK HERE FOR OTHER FETCHERS AND PARSERS.
#
sub do_a_channel_day {
  my($channel,$wanteday) = @_;

  if ($Websource eq "sofcom")
    { &sofcom_channel_day($channel,$wanteday,$fetch_or_make); }
  else { print(STDERR "Unknown Websource $Websource, cannot fetch/parse\n"); }
}
