root/grabbers/oztivo @ 479

Revision 479, 6.6 kB (checked in by lincoln, 6 years ago)

revert half-baked bogus commit to oztivo (work in progress)

Line 
1#!/usr/bin/perl -w
2
3# OzTivo grabber
4
5my $version = '0.13';
6
7# Requires configuration!
8# 1. Register at http://www.tvguide.org.au/
9# 2. Run "./oztivo --configure" to create "oztivo.pw" file.
10#
11# Changelog:
12# 0.1   : Yucky little initial version
13# 0.2   : --ready option
14# 0.3.  : Don't log password
15# 0.4   : Changed password filename
16# 0.5   : Identify user agent; support gzip compression; turn off
17#         output buffering
18# 0.6   : Decodes HTML characters
19# 0.6.1 : Bugfix: Don't decode HTML characters (invalid XMLTV),
20#         Bugfix: translate SBS NEWS XMLTVID properly
21# 0.7   : Decodes apostrophes
22# 0.9   : --configure
23# 0.10  : Minor internal changes to be more forkable
24# 0.11  : Exit on empty config file
25# 0.12  : oztivo has invalid XMLTV (fields in wrong order, empty fields etc)
26#         postprocess these
27# 0.13  : all oztivo programming is in GMT.  add +0000 to its timezone
28#         so the rest of shepherd knows this.
29
30use strict;
31
32use LWP::UserAgent;
33use Cwd;
34use Getopt::Long;
35use HTML::Entities;
36
37my $progname = 'oztivo';
38my $nicename = 'OzTivo';
39my $config_file = cwd() . "/$progname.pw";
40my $output_file = cwd() . "/output.xmltv";
41my $channels_file;
42my $channels, my $opt_channels;
43my @clist;
44my $ver;
45my $ready;
46my $configure;
47my $raw_input;
48my $raw_output;
49
50print "$nicename Grabber v$version\n";
51
52$| = 1;
53
54GetOptions( 
55            'channels_file=s'   => \$channels_file,
56            'output=s'          => \$output_file,
57            'rawoutput=s'       => \$raw_output,
58            'rawinput=s'        => \$raw_input,
59            'version'           => \$ver,
60            'ready'             => \$ready,
61            'configure'         => \$configure
62          );
63
64exit 0 if ($ver);
65
66configure() if ($configure);
67
68unless (-r $config_file)
69{
70    die "Can't find $config_file!\nTry running with the --configure option.\n";
71}
72
73print "Reading configuration file $config_file.\n";
74
75open(CONF, $config_file)
76    or die "Unable to read config file $config_file: $!";
77my $line = <CONF>;
78close CONF;
79
80unless ($line =~ /^(.*):(.*)$/)
81{
82    die "Unable to parse config file!\n" .
83        "Should be in format: username:password\n";
84}
85my ($user, $pw) = ($1, $2);
86
87unless ($user and $pw)
88{
89    die "Failed to extract a sensible username and password from config file!\n";
90}
91
92exit 0 if ($ready);
93
94unless ($channels_file)
95{
96    die "No --channels_file specified.\n";
97}
98
99unless( -r $channels_file)
100{
101    die "Unable to read channels file $channels_file: $!";
102}
103local (@ARGV, $/) = ($channels_file);
104eval <>;
105die "\nError in channels file!\nDetails:\n$@" if ($@);
106
107# Create a list of channel names from longest to shortest
108@clist = sort { length $b <=> length $a } keys %$channels;
109print "Channels: @clist.\n";
110
111my $ua = LWP::UserAgent->new();
112$ua->agent("Shepherd $nicename Grabber/$version");
113$ua->default_header('Accept-Encoding' => 'gzip');
114
115my $fn = "http://$user:YOURPASSWORD\@minnie.tuhs.org/tivo-bin/xmlguide.pl";
116print "Retrieving $fn...\n";
117
118$fn =~ s/YOURPASSWORD/$pw/;
119
120my $data;
121
122if (!defined $raw_input) {
123    my $response = $ua->get($fn);
124    unless ($response->is_success()) {
125        print "Download failed.\n" . $response->status_line() . "\nExiting.\n";
126        exit;
127    }
128    $data = $response->content();
129    print "Downloaded " . int((do {use bytes; length($data)}) / 1024) . "KB.\n";
130
131    if ($response->header('Content-Encoding')
132        and
133        $response->header('Content-Encoding') eq 'gzip') {
134        print "Unzipping.\n";
135        $data = Compress::Zlib::memGunzip($data);
136    }
137
138    if (defined $raw_output) {
139        open(F,">$raw_output") || die "could not write raw output to $raw_output: $!\n";
140        print F $data;
141        close(F);
142        print "Raw output saved in $raw_output.\n";
143    }
144} else {
145    open(F,"<$raw_input") || die "could not read raw input from $raw_input: $!\n";
146    while(<F>) {
147        $data .= $_;
148    }
149    close(F);
150    print "Raw input read from $raw_input.\n";
151}
152
153# print "Decoding HTML.\n";
154# HTML::Entities::decode($data);
155
156print "Converting apostrophes.\n";
157$data =~ s/\&#39;/'/g;
158
159print "Transforming XMLTVIDs.\n";
160$data =~ s/channel="(.*)"/'channel="'.subme($1).'"'/ge;
161
162print "Writing output.\n";
163open (OUT, ">$output_file") || die "could not write to $output_file: $!\n";
164
165#
166# oztivo generates invalid XMLTV with fields out of order and
167# some blank fields.
168# the standard XMLTV.pm perl module gets very unhappy about these
169# write output in a manner which addresses the bad input
170#
171
172my @xmltv_tag_order = qw [ title sub-title desc credits date category language
173        orig-language length icon url country episode-num video audio
174        previously-shown permiere last-chance new subtitles rating
175        star-rating ];
176my %xmltv_tags = map { $_ => "" } @xmltv_tag_order;
177my $linenum = 0;
178my $cur_field = "";
179
180foreach my $line (split/\n/,$data) {
181    $linenum++;
182
183    # oztivo generates blank data for these fields - skip if blank
184    next if ($line =~ /<director><\/director>/);
185    next if ($line =~ /<desc><\/desc>/);
186
187    if ($line =~ /\s*<([\/a-zA-Z\-]+)/) {
188        my $field = lc($1);
189
190        if (($field eq "programme") || ($field eq "/programme")) {
191            # print all previously seen tags in xmltv_tag_order
192            foreach my $xmltag (@xmltv_tag_order) {
193                if ($xmltv_tags{$xmltag} ne "") {
194                    print OUT $xmltv_tags{$xmltag};
195                    $xmltv_tags{$xmltag} = "";
196                }
197            }
198
199            # if we have a start="(time)" and/or stop="(time)" make sure they
200            # have a timezone on them.
201            $line = $1."start=\"".$2." +0000\"".$3 if ($line =~ /^(.*)start="([0-9]+)"(.*)/);
202            $line = $1."stop=\"".$2." +0000\"".$3 if ($line =~ /^(.*)stop="([0-9]+)"(.*)/);
203
204            print OUT $line."\n"; # programme tag
205            $cur_field = "";
206        } else {
207            # do we know about this tag?
208            $cur_field = $field if (defined $xmltv_tags{$field});
209
210            if ($cur_field eq "") {
211                print OUT $line."\n";
212            } else {
213                $xmltv_tags{$cur_field} .= $line."\n";
214            }
215        }
216    } else {
217        print OUT $line."\n";
218    }
219} 
220
221close OUT;
222
223print "Done.\n";
224
225sub configure
226{
227    print "Configuring...\n\n" .
228          "Before you can use the $nicename grabber, you must create an\n" .
229          "account here:\n\n" .
230          '  http://minnie.tuhs.org/twiki/bin/view/TWiki/TWikiRegistration' .
231          "\n\n" .
232          "When you're done, you'll have a username and a password. Enter\n" .
233          "these here.\n\n" .
234          "Username? ";
235    my $username = <>;
236    chomp $username;
237    print "Password? ";
238    my $pw = <>;
239    chomp $pw;
240
241    print "Creating config file $config_file...\n";
242    open (CONF, ">$config_file")
243        or die "Unable to create $config_file: $!";
244    print CONF "$username:$pw";
245    close CONF;
246
247    print "Done.\n";
248    exit 0;
249}
250
251sub subme
252{
253    my $station = shift;
254
255    $station = "SBS NEWS" if ($station eq "SBS-NEWS");
256
257    foreach (@clist)
258    {
259        return $channels->{$_} if ($station =~ /$_/i);
260    }
261    print "Warning: station \"$station\" unknown.\n";
262    return $station;
263}
Note: See TracBrowser for help on using the browser.