~ubuntu-branches/ubuntu/saucy/freeguide/saucy

« back to all changes in this revision

Viewing changes to xmltv/doc/man/tv_grab_eu_epgdata.txt

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Watkins
  • Date: 2008-09-07 15:49:32 UTC
  • mfrom: (1.2.6 upstream) (4.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20080907154932-2jvgv76btq068fe0
Tags: 0.10.9-1
* New upstream release. (Closes: #492789)
* Moved package from contrib to main. (Closes: #492544)
* Added lintian override for 'build-depends-without-arch-dep ant', as ant is
  used in the clean target.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
    tv_grab_eu_epgdata - Grab TV listings for parts of Europe.
3
3
 
4
4
SYNOPSIS
5
 
    tv_grab_eu_epgdata --help
6
 
 
7
 
    tv_grab_eu_epgdata --version
 
5
    tv_grab_eu_epgdata --help tv_grab_eu_epgdata tv_grab_eu_epgdata
 
6
    --version
8
7
 
9
8
    tv_grab_eu_epgdata --capabilities
10
9
 
21
20
    tv_grab_eu_epgdata --list-channels [--config-file FILE] [--output FILE]
22
21
    [--quiet] [--debug]
23
22
 
 
23
    tv_grab_eu_epgdata --preferredmethod
 
24
 
24
25
DESCRIPTION
25
26
    Output TV and listings in XMLTV format for many stations available in
26
27
    Europe.
31
32
    Then running tv_grab_eu_epgdata with no arguments will get a listings
32
33
    for the stations you chose for five days including today.
33
34
 
34
 
    This is a commercial grabber. The data service, www.epgdata.com, plans
35
 
    on granting test accounts to people for the rest of 2007. Mail
36
 
    service@epgdata.com if you want a Test PIN. The future of this grabber
37
 
    is a little bit unclear as of now; it's likely you'll have to pay a
38
 
    small sum to use it (beginning 2008).
 
35
    This is a commercial grabber. Go to
 
36
    http://wiki.xmltv.org/index.php/EU_epgdata to sign up or send an e-mail
 
37
    to service@epgdata.com for further information. It's also possible to
 
38
    ask for a test account.
39
39
 
40
40
OPTIONS
41
41
    --configure Prompt for which stations to download and write the
58
58
 
59
59
    --offset N Start grabbing at today + N days.
60
60
 
61
 
    --quiet Suppress the progress-bar normally shown on standard error. This
62
 
    option does not do anything right now.
 
61
    --quiet Do not show status messages.
63
62
 
64
63
    --debug Provide more information on progress to stderr to help in
65
 
    debugging. This option does not do anything right now.
 
64
    debugging.
66
65
 
67
66
    --list-channels Output a list of all channels that data is available
68
67
    for. The list is in xmltv-format.
71
70
 
72
71
    --help Print a help message and exit.
73
72
 
74
 
ERROR HANDLING
75
 
    N/A
 
73
    --preferredmethod Shows the preferred method for downloading data (see
 
74
    http://xmltv.org/wiki/xmltvcapabilities.html) =head1 ENVIRONMENT
 
75
    VARIABLES
76
76
 
77
 
ENVIRONMENT VARIABLES
78
77
    The environment variable HOME can be set to change where configuration
79
78
    files are stored. All configuration is stored in $HOME/.xmltv/. On
80
79
    Windows, it might be necessary to set HOME to a path without spaces in
83
82
SUPPORTED CHANNELS
84
83
    For a list of supported channels, see the channel_ids file distributed
85
84
    with this grabber. If additional channels are available, you will
86
 
    receive a warning when you run --configure. In the future, it might be
87
 
    possible to download an updated channel_ids file from the internet.
 
85
    receive a warning when you run --configure.
 
86
 
 
87
    Once I am aware that new channels are available, the channel_ids file
 
88
    will be updated and this grabber will automatically fetch an updated
 
89
    copy.
88
90
 
89
91
COMPATIBILITY
90
92
    The channel ids used in this grabber aim to be mostly possible with
105
107
    schedule for Germany even if you preferred the Swiss schedule which is
106
108
    also available in the data (for some channels at least).
107
109
 
108
 
    The EPG package code is not properly detected during the configure stage
109
 
    and 'y' is assumed. The package code determines which channel_?.xml is
110
 
    loaded.
111
 
 
112
110
    Timezones are not handled correctly. Currently, you have to enter your
113
111
    time zone manually during the configure step. You have to do this every
114
112
    time your time zone changes, eg for daylight saving time ("Sommerzeit"
126
124
    grab yesterday because that'll give us EPG till ~5am for today.
127
125
 
128
126
    I'm sure this list is not complete. Let me know if you encounter
129
 
    additional problems. =cut
130
 
 
131
 
    use strict; use LWP::Simple qw($ua getstore); use Archive::Zip; use
132
 
    File::Temp qw/ tempdir /; use XML::Twig;
133
 
 
134
 
    use XMLTV; use XMLTV::Options qw/ParseOptions/; use
135
 
    XMLTV::Configure::Writer; use XMLTV::Supplement qw/GetSupplement/;
136
 
 
137
 
    # deal with umlauts use HTML::Entities;
138
 
 
139
 
    use XMLTV::Memoize; XMLTV::Memoize::check_argv('getstore');
140
 
 
141
 
    # set user agent $ua->agent("xmltv/$XMLTV::VERSION");
142
 
 
143
 
    our $tmp= tempdir( CLEANUP => 1 ) . '/'; #our $tmp = "/tmp/foobarbaz/";
144
 
 
145
 
    # set up XML::Twig our $epg= new XML::Twig( twig_handlers => { data =>
146
 
    \&printepg } ); our $channels = new XML::Twig( twig_handlers => { data
147
 
    => \&printchannels } ); our %genre; our $genre = new XML::Twig(
148
 
    twig_handlers => { data => \&makegenrehash } );
149
 
 
150
 
    # build a hash: epgdata.com channel id -> xmltv channel id my $chanids =
151
 
    GetSupplement( 'tv_grab_eu_epgdata', 'channel_ids' );
152
 
 
153
 
    our %chanid; my @lines = split( /[\n\r]+/, $chanids ); foreach my $line
154
 
    (@lines) { if ($line !~ '^#') { my @chanid_array = split(';', $line);
155
 
    chomp($chanid_array[1]); $chanid{$chanid_array[0]}= $chanid_array[1]
156
 
    unless $line =~ '^#'; } }
157
 
 
158
 
    my( $opt, $conf ) = ParseOptions( { grabber_name =>
159
 
    "tv_grab_eu_epgdata", capabilities => [qw/baseline manualconfig tkconfig
160
 
    apiconfig cache/], stage_sub => \&config_stage, listchannels_sub =>
161
 
    \&list_channels, version => '$Id: tv_grab_eu_epgdata.in,v 1.3 2007/11/04
162
 
    17:35:41 mihaas Exp $', description => "Parts of Europe (commercial)
163
 
    (www.epgdata.com)", } );
164
 
 
165
 
    our $pin = $conf->{pin}->[0]; die 'Sorry, your PIN is not defined. Run
166
 
    tv_grab_eu_epgdata --configure to fix this.' unless defined($pin);
167
 
 
168
 
    our $tz = $conf->{tz}->[0]; # die 'Sorry, time zone is not defined. Run
169
 
    tv_grab_eu_epgdata --configure to fix this.' unless defined($tz); #
170
 
    Oops. Looks like the line below will result in a warning # telling us
171
 
    that we're declaring $tz twice. However, this does not seem to # be an
172
 
    issue. our $tz = '+0100' unless defined($tz);
173
 
 
174
 
    sub config_stage { # shamelessly stolen from
175
 
    http://xmltv.org/wiki/howtowriteagrabber.html
176
 
 
177
 
        my( $stage, $conf ) = @_;
178
 
        # Sample stage_sub that only needs a single stage.
179
 
        die "Unknown stage $stage" if $stage ne "start";
180
 
 
181
 
        my $result;
182
 
        my $configwriter = new XMLTV::Configure::Writer( OUTPUT => \$result,
183
 
                                                         encoding => 'ISO-8859-1' );
184
 
        $configwriter->start( { grabber => 'tv_grab_eu_epgdata' } );
185
 
        $configwriter->write_string( {
186
 
            id => 'pin', 
187
 
            title => [ [ 'Enter your PIN for epgdata.com', 'en' ] ],
188
 
            description => [ 
189
 
            [ 'This alphanumeric string is used for authentication with epgdata.com. 
190
 
            Ask service@epgdata.com for a test PIN (before 2007 ends)',
191
 
                'en' ] ],
192
 
            default => '',
193
 
        } );
194
 
        $configwriter->write_string( {
195
 
            id => 'tz', 
196
 
            title => [ [ 'Time zone for your EPG data', 'en' ] ],
197
 
            description => [ 
198
 
            [ 'Enter the time offset from UTC here. Think of it as your time zone. 
199
 
            For example: during winter in Germany, you should enter "+0100". During summer, use "+0200". (without quotation marks) ',
200
 
                'en' ] ],
201
 
            default => '+0100',
202
 
        } );
203
 
    
204
 
        $configwriter->end( 'select-channels' );
205
 
        return $result;
206
 
    }
207
 
 
208
 
    # construct writer object # taken from tv_grab_na_dd (XMLTV 0.4.45) #
209
 
    XMLTV::Options does not redirect stdout properly for us # XML::Twig
210
 
    probably messes it up, I don't know. :/ my %w_args; if (defined
211
 
    $opt->{output}) { my $fh = new IO::File(">$opt->{output}"); die "ERROR:
212
 
    cannot write to $opt->{output}: $!" if not defined $fh; $w_args{OUTPUT}
213
 
    = $fh; } $w_args{encoding} = 'ISO-8859-1';
214
 
 
215
 
    our $writer = new XMLTV::Writer(%w_args);
216
 
 
217
 
    downloadepg(); prepareinclude($conf); # it looks like we can also
218
 
    extract the language from the file # name of the epg data our @xmlfiles
219
 
    = glob($tmp . "*_*_??_q?.xml"); processxml();
220
 
 
221
 
    sub downloadepg { my $days = $opt->{days}; my $offset = $opt->{offset};
222
 
    my $i='0'; # we've got to start counting at 0 # if we did "$i <= $days",
223
 
    we'd end up with one zip file too much while ( $i < $days) { my
224
 
    $dataoffset = $i +$offset; my $baseurl="http://www.epgdata.com"; my
225
 
    $url=$baseurl . '/index.php?action=sendPackage&iOEM=&pin=' . $pin .
226
 
    '&dayOffset=' . $dataoffset . '&dataType=xml'; getstore($url, $tmp .
227
 
    "epgzip" . $dataoffset); # This doesn't seem to work correctly. # It
228
 
    doesn't fail even if the PIN is wrong. #unless (getstore($url, $tmp .
229
 
    "epgzip" . $dataoffset) == 200) { #die "Couldn't download epg file\n";
230
 
    #} $i++; } # FIXME: we can easily create a list of files earlier in this
231
 
    function my @zipfiles=(glob($tmp . 'epgzip*')); unzip(@zipfiles); }
232
 
 
233
 
    # for simplicity's sake, always call with $conf as argument at least sub
234
 
    prepareinclude { my ( $conf, $opt ) = @_; my
235
 
    $baseurl="http://www.epgdata.com"; my $pin = $conf->{pin}->[0]; my
236
 
    $includeurl=$baseurl . "/index.php?action=sendInclude&iOEM=&pin=" . $pin
237
 
    . "&dataType=xml"; getstore($includeurl, $tmp . "includezip"); # This
238
 
    doesn't seem to work correctly. # It doesn't fail even if the PIN is
239
 
    wrong. # unless (getstore($includeurl, $tmp . "includezip") == 200) { #
240
 
    die "Couldn't download include file\n"; # } my @zipfiles=( $tmp .
241
 
    "includezip"); unzip(@zipfiles) }
242
 
 
243
 
    sub unzip { foreach my $zipfile (@_) { my $zip = Archive::Zip->new(
244
 
    $zipfile ); my @filelist = $zip->memberNames; foreach my $ext (("\.dtd",
245
 
    "\.xml")) { foreach my $filename (@filelist) { # we only care about .dtd
246
 
    and .xml right now my $xmlfile=$filename if $filename =~ /$ext/;
247
 
    $zip->extractMember( $xmlfile, $tmp . $xmlfile ) if defined $xmlfile; }
248
 
    } } }
249
 
 
250
 
    sub processxml { $writer->start({ 'generator-info-name' =>
251
 
    'tv_grab_eu_epgdata' }); $genre->parsefile($tmp . 'genre.xml');
252
 
    $channels->parsefile($tmp . 'channel_' . findchannelcode($xmlfiles[0],
253
 
    $tmp) . '.xml'); foreach my $xmlfile (@xmlfiles) {
254
 
    $epg->parsefile($xmlfile); } $writer->end(); }
255
 
 
256
 
    sub makegenrehash { my( $twig, $genre)= @_; my $genreid =
257
 
    $genre->first_child('g0')->text; my $genrename =
258
 
    decode_entities($genre->first_child('g1')->text); $genre{$genreid}=
259
 
    $genrename; $twig->purge; }
260
 
 
261
 
    sub printepg { my( $twig, $sendung)= @_; my $internalchanid =
262
 
    $sendung->first_child('d2')->text; my $internalregionid =
263
 
    $sendung->first_child('d3')->text; our $chanid; if (defined
264
 
    $main::chanid{$internalchanid}) { $chanid =
265
 
    $main::chanid{$internalchanid}; } else { $chanid = $internalchanid; #
266
 
    FIXME: not sure if this is correct. # Maybe we should behave differently
267
 
    if we encounter an unknown ID, # but this ought to be OK for now } #
268
 
    alright, let's try this: # push the channel ids we want to grab in an
269
 
    array # http://effectiveperl.blogspot.com/ my %configuredchannels = map
270
 
    { $_, 1 } @{$conf->{channel}}; # does the channel we're currently
271
 
    processing exist in the hash? # BTW: this is not a lot more efficient in
272
 
    our case than looping over a list # but a few seconds are better than
273
 
    nothing :) if($configuredchannels{$chanid} && $internalregionid == '0')
274
 
    { my $title = decode_entities($sendung->first_child('d19')->text); my
275
 
    $subtitle = decode_entities($sendung->first_child('d20')->text); my
276
 
    $desc = decode_entities($sendung->first_child('d23')->text); my $start =
277
 
    $sendung->first_child('d4')->text; my $internalgenreid =
278
 
    $sendung->first_child('d25')->text; my $rating =
279
 
    $sendung->first_child('d30')->text; my $wide_aspect =
280
 
    $sendung->first_child('d29')->text; # black and white? my $bw_colour =
281
 
    $sendung->first_child('d11')->text; my $stereo_audio =
282
 
    $sendung->first_child('d27')->text; my $dolby_audio =
283
 
    $sendung->first_child('d28')->text; # I was told that technics_hd is
284
 
    supposed to exist # However, it's not listed in qy.dtd # my $hd_video =
285
 
    $sendung->first_child('XXX')->text;
286
 
 
287
 
                $start =~ s/-//g;
288
 
                $start =~ s/://g;
289
 
                $start =~ s/ //g;
290
 
                our %prog = ("channel" => $chanid, "start" => "$start $tz",
291
 
                    "title" => [ [ $title ] ]);
292
 
 
293
 
                 if ( length($subtitle) > 0 ) {
294
 
                    push @{$prog{'sub-title'}}, [$subtitle];
295
 
                }
296
 
            
297
 
                if (exists $genre{$internalgenreid} ) {
298
 
                    push @{$prog{'category'}}, [$genre{$internalgenreid}];
299
 
                }
300
 
            
301
 
                if (length($desc) > 0 ) {
302
 
                    push @{$prog{'desc'}}, [$desc];
303
 
                }
304
 
 
305
 
                # star-rating: the data source seems to say <d30>0</d30> 
306
 
                # if they mean "unknown"
307
 
                # valid values seem to be 1 to 5
308
 
                # FIXME: when I did a quick grep, '2' didn't show up
309
 
                # is this intentional or just a coincidence?
310
 
 
311
 
                if ( $rating gt 0 ) {
312
 
                    $prog{'star-rating'} = ["$rating/5"];
313
 
                }
314
 
 
315
 
                if ($wide_aspect == 1 ) {
316
 
                    $prog{'video'}->{'aspect'} = '16:9';
317
 
                }
318
 
 
319
 
                if ($bw_colour == 1 ) {
320
 
                    $prog{'video'}->{'colour'} = '0';
321
 
 
322
 
                }
323
 
 
324
 
                # check for dolby first
325
 
                # not sure if dolby_audio and stereo_audio can be true 
326
 
                # simultaneously in the source data, but it's better to be 
327
 
                # on the safe side.
328
 
                # If stereo_audio is false, is it safe to assume the programme
329
 
                # will be broadcast in mono?
330
 
                # I mean, this is the 21th century, right?
331
 
                # Also, what does dolby mean in this context? 
332
 
                # How does it apply to analog broadcasts?
333
 
                if ($dolby_audio == 1) {
334
 
                     $prog{'audio'}->{'stereo'} = 'dolby';
335
 
                }
336
 
                elsif ($stereo_audio == 1) {
337
 
                    $prog{'audio'}->{'stereo'} = 'stereo';
338
 
                }
339
 
 
340
 
                $writer->write_programme(\%main::prog);
341
 
            
342
 
        }
343
 
      $twig->purge;
344
 
    }
345
 
 
346
 
    # we need to extract some information from the xml filename supplied #
347
 
    by epgdata.com # the last letter tells us which channel_?.xml we need
348
 
 
349
 
    sub findchannelcode { # let's just use the first xml file name for that
350
 
    # thanks to Dagmar for the regexp my ($filename, $tmp) = @_; $filename
351
 
    =~ s/.*(.)\.xml$/$1/;; return $filename; }
352
 
 
353
 
    # this is called as a handler for the channels twig # which is in turn
354
 
    called by processxml() sub printchannels { my( $twig, $sendung)= @_; my
355
 
    $internalchanid = $sendung->first_child('ch4')->text; our $chanid; if
356
 
    (defined $main::chanid{$internalchanid}) { $chanid =
357
 
    $main::chanid{$internalchanid}; } else { $chanid = $internalchanid; #
358
 
    FIXME: not sure if this is correct. # Maybe we should just return if we
359
 
    don't know the channel id } my $name =
360
 
    decode_entities($sendung->first_child('ch0')->text); foreach my $channel
361
 
    (@{$conf->{channel}}) { if($channel eq $chanid) { my %ch = (id =>
362
 
    $chanid, 'display-name' => [ [ $name ] ]); $writer->write_channel(\%ch);
363
 
    } } }
364
 
 
365
 
    # this list all _available_ channels # used for --configure #
366
 
    independent from printchannels which will print list of configured
367
 
    channels sub list_channels { my ( $conf, $opt ) = @_;
368
 
    prepareinclude($conf, $opt); # borrowed from
369
 
    http://www.xmltwig.com/xmltwig/ex_fm1 # FIXME: must not hardcode package
370
 
    code! $channels->parsefile($tmp . 'channel_y.xml'); my $channel_list=
371
 
    $channels->root; my @channels= $channel_list->children;
372
 
 
373
 
        my $xmltv_channel_list = "<tv generator-info-name=\"tv_grab_eu_epgdata\">\n";
374
 
 
375
 
        foreach my $channel  (@channels) {
376
 
            my $internalchanid = $channel->first_child('ch4')->text;
377
 
            our $chanid;
378
 
            if (defined $main::chanid{$internalchanid}) {
379
 
                $chanid = $main::chanid{$internalchanid};
380
 
            }
381
 
            else {
382
 
                $chanid = $internalchanid;
383
 
                warn "New channel with ID $internalchanid found. Please update channel_ids file!"
384
 
            }
385
 
 
386
 
            my $name = $channel->first_child('ch0')->text;
387
 
        $xmltv_channel_list = <<END;
388
 
        $xmltv_channel_list
389
 
        <channel id="$chanid">
390
 
        <display-name>$name</display-name> 
391
 
        </channel>
392
 
    END
393
 
         }
394
 
         $xmltv_channel_list = $xmltv_channel_list . "</tv>";
395
 
         return $xmltv_channel_list
396
 
    }
 
127
    additional problems.
 
128