--- Begin Message ---
Package: xmltv
Version: 0.5.63-2
Severity: normal
Tags: patch
User: [email protected]
Usertags: origin-ubuntu vivid ubuntu-patch
*** /tmp/tmpJ_KmSS/bug_body
In Ubuntu, the attached patch was applied to achieve the following:
* Apply patch from upstream CVS to fix tv_grab_hu_ro. (LP: #1438237)
Thanks for considering the patch.
-- System Information:
Debian Release: jessie/sid
APT prefers vivid-updates
APT policy: (500, 'vivid-updates'), (500, 'vivid-security'), (500, 'vivid'),
(100, 'vivid-backports')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.19.0-10-generic (SMP w/4 CPU cores)
Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
diff -Nru xmltv-0.5.63/debian/changelog xmltv-0.5.63/debian/changelog
diff -Nru xmltv-0.5.63/debian/patches/series xmltv-0.5.63/debian/patches/series
--- xmltv-0.5.63/debian/patches/series 2012-06-28 17:36:39.000000000 -0400
+++ xmltv-0.5.63/debian/patches/series 2015-03-31 07:42:48.000000000 -0400
@@ -1,3 +1,4 @@
it_dvb_linux_warning
11_makefile_pl_debian_changes.diff
tv_grab_huro.patch
+tv_grab_huro_2.patch
diff -Nru xmltv-0.5.63/debian/patches/tv_grab_huro_2.patch xmltv-0.5.63/debian/patches/tv_grab_huro_2.patch
--- xmltv-0.5.63/debian/patches/tv_grab_huro_2.patch 1969-12-31 19:00:00.000000000 -0500
+++ xmltv-0.5.63/debian/patches/tv_grab_huro_2.patch 2015-03-31 07:42:48.000000000 -0400
@@ -0,0 +1,578 @@
+Description: _huro: unbreak after changes to source site.
+Origin: upstream, http://xmltv.cvs.sourceforge.net/viewvc/xmltv/xmltv/grab/huro/tv_grab_huro.in?r1=1.48&r2=1.54
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/xmltv/+bug/1438237
+Author: POJAR GEORGE (credit: Zoltán Karcagi)
+Index: xmltv-0.5.63/grab/huro/tv_grab_huro.in
+===================================================================
+--- xmltv-0.5.63.orig/grab/huro/tv_grab_huro.in
++++ xmltv-0.5.63/grab/huro/tv_grab_huro.in
+@@ -2,7 +2,7 @@
+ # vi:noet:ts=4
+
+ #-------------------------------------------------------------------------------
+-# $Id: tv_grab_huro.in,v 1.48 2012/06/19 06:32:25 dekarl Exp $
++# $Id: tv_grab_huro.in,v 1.54 2015/01/13 07:15:29 bilbo_uk Exp $
+ #-------------------------------------------------------------------------------
+
+ #-------------------------------------------------------------------------------
+@@ -122,7 +122,7 @@ recommended by the XMLTV DTD.
+ #-------------------------------------------------------------------------------
+
+ use strict;
+-use XMLTV::Version '$Id: tv_grab_huro.in,v 1.48 2012/06/19 06:32:25 dekarl Exp $';
++use XMLTV::Version '$Id: tv_grab_huro.in,v 1.54 2015/01/13 07:15:29 bilbo_uk Exp $';
+ use XMLTV::Capabilities qw/baseline manualconfig cache/;
+ use XMLTV::Description 'Hungary/Romania';
+ use XMLTV::Supplement qw/GetSupplement/;
+@@ -195,14 +195,18 @@ our %COUNTRIES = (Hungary => [ 'hu', '+0
+ Romania => [ 'ro', '+0200' ],
+ Slovakia => [ 'sk', '+0100' ]);
+ our %WORDS = (
+- cz => { episode => "Epizoda"},
++ cz => { episode => "Epizoda",
++ minute => "minut",
++ links => "Linky" },
+ hu => { episode => "rész",
+ minute => "perc",
+ links => "linkek" },
+- ro => { episode => "no such info on webpage",
++ ro => { episode => "episodul", # patch #84
+ minute => "minute",
+ links => "Linkuri" },
+- sk => { episode => "Epizóda"}
++ sk => { episode => "Epizóda",
++ minute => "minút",
++ links => "Linky" }
+ ) ;
+
+ sub domain();
+@@ -210,9 +214,10 @@ sub xid( $ );
+ sub xhead();
+ sub process_table( $$$$ );
+ sub parse_short_desc ( $ );
+-sub get_channels();
++sub get_channels( ;$ );
+ sub get_infourl_data( $$ );
+ sub add_person ( $$$ );
++sub extract_episode( $ );
+ sub grab_icon( $ );
+ sub get_channel_urls( $ );
+ sub worker( $ );
+@@ -307,7 +312,7 @@ sub process_table( $$$$ ) {
+
+ my $basedateday = UnixDate(parse_date($basedate), '%e');
+ my $urlfmt = "http://www." . domain() .
+- "/pls/tv/tv.channel?i_ch=$ch_port_id" .
++ "/pls/tv/".($COUNTRY eq 'hu' ? 'old' : '')."tv.channel?i_ch=$ch_port_id" .
+ "&i_date=%d&i_xday=".$days_to_request."&i_where=1";
+ my $url = "$urlfmt";
+ my $currday = $baseday + $FETCHOFFSET - 1;
+@@ -333,11 +338,11 @@ sub process_table( $$$$ ) {
+ worker("base-downloading");
+ $XMLTV::Get_nice::FailOnError = 1;
+ my $data=get_nice($url);
+- # FIXME strip sponsored links, they don't work in xmltv anyway
+- $data =~ s|\x0D||g; # strip carriage return
++ # strip links to bet-at-home.com # bug #447
++ $data =~ s|\x0A||g; # strip new line
+ $data =~ s|<span class=\"spons_link.*?</span>||g;
+- $data =~ s|<div style=\"display:none\">.*?</div>||g;
+- # strip links to divido.hu
++ $data =~ s|<script type=\"text\/javascript\">.*?</script>||g;
++ # strip links to divido.hu and provideo.ro
+ $data =~ s|<a onclick=\"loggin.*?</a>||g;
+
+ $tree = HTML::TreeBuilder->new_from_content($data) or
+@@ -484,7 +489,7 @@ sub process_table( $$$$ ) {
+
+ my $begin_time;
+ # this matches the currently running programme only:
+- if ($col->attr("colspan") && ($begin_time = $col->look_down("_tag"=>"p", "class"=>"begin_time" )))
++ if ($col->attr("colspan") && ($begin_time = $col->look_down("_tag"=>"p", "class"=>"begin_time" )))
+ {
+ $_ = $begin_time->as_text();
+ } elsif ($begin_time = $col->look_down("_tag"=>"td", "class"=>"time_container")) {
+@@ -531,7 +536,8 @@ sub process_table( $$$$ ) {
+ else {
+ warn "cannot found title: $startdate" ;
+ }
+- # add one space after the title, if there is none
++ # add one space after the title, if there is none # ???
++ $program{title} = ' ' if $program{title} eq ''; # bug #408
+ my @tmp = get_all_text($col);
+ $_ = join(' ', @tmp);
+ s/ +/ /g;
+@@ -713,23 +719,30 @@ sub parse_short_desc ($) {
+ }
+
+ t "parse_short_desc: text: '$cont'";
+- $WORDS{$COUNTRY}->{episode}="zdontmatchz" unless exists $WORDS{$COUNTRY}->{episode};
+- # port.hu episode style
+- if (m/\s*([0-9\/]+)\. $WORDS{$COUNTRY}->{episode}/) { $episode = $1; }
++ $WORDS{$COUNTRY}->{episode}="zdontmatchz" unless exists $WORDS{$COUNTRY}->{episode};
++ # port.hu episode style with season (# patch #80)
++ if (m/\s*([IVX]+\.\/[0-9]+)\. $WORDS{$COUNTRY}->{episode}/) { $episode = $1; }
++ # port.hu episode style without season
++ elsif (m/\s*([0-9\/]+)\. $WORDS{$COUNTRY}->{episode}/) { $episode = $1; }
++ # port.ro episode style with season (# patch #74)
++ elsif (m/$WORDS{$COUNTRY}->{episode} \s*([0-9]+, [A-Za-z]+ [0-9])/) { $episode = $1; }
+ # port.cz/.sk episode style with season
+- elsif (m/$WORDS{$COUNTRY}->{episode} \s*([0-9]+, [IVX]+\.)/) { $episode = $1; }
++ elsif (m/$WORDS{$COUNTRY}->{episode} \s*([0-9]+, [IVX]+)\./) { $episode = $1; }
+ # port.cz/.sk episode style for two episodes back to back in one slot
+ elsif (m/$WORDS{$COUNTRY}->{episode} \s*(\d+, \d+)/) { $episode = $1; }
+- # port.cz/.sk episode style without season
++ # port.cz/.sk/.ro episode style without season
+ elsif (m/$WORDS{$COUNTRY}->{episode} \s*([0-9\/]+)/) { $episode = $1; }
++
+ if (m/\s*(\d+)'/) { $minutes = $1; }
+- if (m/\s*([12][0-9]{3})/) { $year = $1 }
++ if (m/\(.*?((?:19|20)[0-9]{2})/) { $year = $1 } # bug #448
+
+ t "found episode: '$episode'" if defined $episode;
+ t "found minutes: '$minutes'" if defined $minutes;
+ t "found year: '$year'" if defined $year;
+
+- foreach (keys %CATMAP) {
++ # Sort the category keys so they appear in consistent order
++ foreach (sort keys %CATMAP) {
++ next unless defined $CATMAP{$_}; # bug #443
+ if ($cont =~ /$CATMAP{$_}[0]/i) {
+ push @categories, [$_, "en"];
+ push @categories, [$CATMAP{$_}[1], $COUNTRY];
+@@ -740,33 +753,10 @@ sub parse_short_desc ($) {
+ $prog->{q(category)} = \@categories if @categories;
+ $prog->{q(length)} = $minutes * 60 if defined $minutes;
+ $prog->{q(date)} = $year if defined $year ;
+- if (defined($episode)) {
+- if($episode =~ m#(\d+)/(\d+)#) {
+- my $current = $1;
+- my $total = $2;
+- # swap numbers for port.hu, they have total/current
+- if ($current > $total) {
+- ($total, $current) = ($current, $total);
+- }
+- # episode-num spec with the total number specified.
+- # however XMLTV counts from 0 on ...
+- $prog->{q(episode-num)} = [[ sprintf('. %d/%d .', $current - 1, $total), "xmltv_ns" ],
+- [ $episode, "onscreen" ]];
+- } elsif($episode =~ m#(\d+), ([IVX]+)#) {
+- # decode season from roman numeral
+- my $season = arabic ($2);
+- # episode-num spec with the total number specified.
+- # however XMLTV counts from 0 on ...
+- $prog->{q(episode-num)} = [[ sprintf('%d . %d .', $season - 1, $1 - 1), "xmltv_ns" ],
+- [ $episode, "onscreen" ]];
+- } elsif($episode =~ m#(\d+)#) {
+- # episode-num spec with just the episode number
+- # however XMLTV counts from 0 on ...
+- $prog->{q(episode-num)} = [[ sprintf('. %d .', $1 - 1), "xmltv_ns" ]];
+- } else {
+- $prog->{q(episode-num)} = [[ $episode, "onscreen" ]];
+- }
+- }
++
++ $prog->{q(episode-num)} = extract_episode( $episode )
++ if defined $episode ;
++
+ }
+
+ #-------------------------------------------------------------------------------
+@@ -800,11 +790,12 @@ sub get_nice_gzip( $ ) {
+ # 'id' => "$channel_id.$d",
+ # 'icon' => [ { src => $iconurl } ] )
+ #-------------------------------------------------------------------------------
+-sub get_channels() {
++sub get_channels( ;$ ) {
++ my $mode = shift;
+ my $d = domain();
+ my $bar = new XMLTV::ProgressBar('getting list of channels', 1)
+ if not $opt_quiet;
+- my $url="http://www.$d/pls/tv/tv.prog";
++ my $url="http://www.$d/pls/tv/".($COUNTRY eq 'hu' ? 'old' : '')."tv.prog";
+
+ worker("base-downloading");
+ t "fetching $url...";
+@@ -838,12 +829,14 @@ sub get_channels() {
+ 'display-name' => [ [ $channel_name, $COUNTRY ] ],
+ 'id' => "$channel_id.$d"
+ ) ;
++ if (!defined $mode || $mode ne 'grab') { # no point doing this for 'grab'
+ # fetch and get icon url
+ worker("base-downloading");
+ if (my $iconurl = grab_icon( $channel_id )) {
+ $channel{'icon'} = [ { src => $iconurl } ];
+ }
+ worker("base-parsing");
++ }
+ $CHANNELS{$channel_id} = \%channel;
+ }
+ }
+@@ -871,13 +864,14 @@ sub add_person ( $$$ ) {
+
+ return unless length($person);
+
+- if (defined($JOBMAP{$job})) {
++ # suppress if job is not known, or if not mapped to DTD
++ if (defined $JOBMAP{$job} && length($JOBMAP{$job})) {
+ push @{$$rcredits{$JOBMAP{$job}}}, $person;
++ t "credits: added: '$job -> $person'";
+ }
+ else {
+- push @{$$rcredits{'actor'}}, $person;
++ t "credits: NOT added: '$job -> $person'";
+ }
+- t "credits: added: '$job -> $person'";
+ }
+
+
+@@ -953,6 +947,7 @@ sub get_infourl_data( $$ ) {
+
+ t "subtitle parsing ...";
+ ($anchor) = $tree->look_down(_tag=>"span", class=>"blackbigtitle");
++ ($anchor) = $tree->look_down(_tag=>"h1", class=>"blackbigtitle") if !defined $anchor; # 2014-04-09 it seems to now be in <h1>
+ if ($anchor) {
+ $elem = $anchor;
+ my ($engtitle, @tmp);
+@@ -976,10 +971,27 @@ sub get_infourl_data( $$ ) {
+ $joined =~ s/\xA0//; # remove the to_text()'s results of  
+ $joined =~ s/^\s+//; # remove blanks
+ $joined =~ s/\s+$//; # remove blanks
++ $joined =~ s/,$//; # remove trailing comma
+ t "anchor and right sibling found, joinedlines parsed :'$joined'";
+ $prog->{q(sub-title)} = [[$joined, $COUNTRY]] if length($joined);
+ }
+
++ # ICON
++ # anchor point:
++ # the programme image will be tagged as follows:
++ # <div class="random-media-wrapper"><img class="object_picture" src="http://media.port-network.com/picture/instance_2/92418_2.jpg" width="250" height="221" style="float:" alt="Închisoarea îngerilor - Tim Robbins" border="0" />
++
++ t "programme icon parsing ...";
++ $anchor = $tree->look_down(_tag=>"div", class=>"random-media-wrapper");
++ $anchor = $anchor->look_down(_tag=>"img", class=>"object_picture") if $anchor;
++ if ($anchor) {
++ my %icon;
++ $icon{'src'} = $anchor->attr('src') if $anchor->attr('src');
++ $icon{'width'} = $anchor->attr('width') if $anchor->attr('width');
++ $icon{'height'} = $anchor->attr('height') if $anchor->attr('height');
++ $prog->{q(icon)} = [ \%icon ] if $anchor->attr('src');
++ }
++
+ # LINKS:
+ # try to grab IMDB, All Movie, official web site of the program
+ # anchor point:
+@@ -1041,7 +1053,7 @@ sub get_infourl_data( $$ ) {
+ $joined = join(" ", @lines);
+ $joined =~ s/\xA0//; # remove the to_text()'s results of  
+ $joined =~ s/^\s+//; # remove blanks
+- t "found description $joined";
++ t "found description: $joined";
+
+ if (length($joined)) {
+ delete($prog->{q(desc)});
+@@ -1068,11 +1080,84 @@ sub get_infourl_data( $$ ) {
+ return if ($#separators < 1);
+
+ ($anchor) = $separators[1];
+- if ($anchor->parent()->tag() ne "td" || $anchor->parent->attr('width') ne "98%") {
++ if ($anchor->parent()->tag() ne "td" || !defined $anchor->parent->attr('width') || $anchor->parent->attr('width') ne "98%") { # bug #445
+ t "credits section not found";
+ return;
+ }
+
++ # get the rating if available
++ # <img alt="(AP)" title="Recomandat acordul parintilor" class="age_limit_icon" src="http://media.port-network.com/page_elements/parental_guidance_mini_pix_ro.png">
++ if (my $img = $anchor->parent()->look_down('_tag' => 'img', 'class' => 'age_limit_icon')) {
++ my $rating = $img->attr('alt');
++ $rating =~ s/[\(\)]//g; # strip the brackets
++ my $rating_icon = $img->attr('src');
++ $prog->{q(rating)} = [[ $rating, '', [{'src' => $rating_icon }] ]];
++ }
++
++ # unfortunately the star-rating (vote_box) if fetched with an AJAX call
++ # e.g. http://www.port.sk/arrow/pls/fi/vote.print_vote_box?i_object_id=139692&i_area_id=6&i_reload_container=id%3D%22vote_box%22&i_is_separator=0
++ #
++ # we could use TreeBuilder->store_cdata(true) to store the cdata under the root node, but I think it's easier to just regexp the html
++ # /*<![CDATA[*/
++ # ajaxRequest(
++ # {'url':'vote.print_vote_box?',
++ # 'parameters':'i_object_id=139692&i_area_id=6&i_reload_container=id%3D%22vote_box%22&i_is_separator=0',
++ # 'method':'GET',
++ # ...
++ #
++ if ( $data =~ m/ajaxRequest\(.*?{'url':'(vote.print_vote_box\?)',.*?'parameters':'(.*?)',.*?'method':'GET'/s ) {
++
++ my $ajaxurl = $1 . $2; # ajax uri
++ (my $baseurl) = $url =~ m#(.*/)#; # greedy match up to last / char
++ $ajaxurl = $baseurl . $ajaxurl; # prepend the uri
++
++ t "fetching ajax url" . d $ajaxurl;
++
++ # store current values of get_nice
++ my $get_fail = $XMLTV::Get_nice::FailOnError;
++ my $get_delay = $XMLTV::Get_nice::Delay;
++ $XMLTV::Get_nice::FailOnError = 0; # don't abort if not found
++ $XMLTV::Get_nice::Delay = 0; # no delay
++
++ my $ajaxdata;
++ if (defined($ajaxdata = get_nice($ajaxurl))) {
++ worker("ajax-downloading");
++ my $ajaxtree = HTML::TreeBuilder->new_from_content($ajaxdata) or
++ die "could not fetch/parse $ajaxurl (infopage)";
++
++ worker("ajax-parsing");
++
++ # get the "star-rating"
++ # The rating includes the number of votes. Testing for statistical significance calculates that, at
++ # a confidence level of .95, a population of 100 will give 70% confidence in the score being accurate
++ # (and is largely independent of population size).
++ # Therefore only output the rating where the population is > 100.
++ #
++ if (my $anchor = $ajaxtree->look_down(_tag=>"div", class=>qr/starholder/)) {
++ my $starsval;
++ if (my $stars = $anchor->look_down(_tag=>"span", class=>"ctxt")) {
++ $starsval = $stars->as_text();
++ $starsval =~ s/,/./; $starsval += 0; # convert to float
++ }
++ if (my $votes = $anchor->look_down(_tag=>"div", class=>"votenum")) {
++ my $votesval = $votes->as_text();
++ if ($votesval) {
++ (my $num_votes) = $votesval =~ /(\d*)/;
++ # if number of votes is >100 then output the star-rating
++ if ($num_votes ne '' && int($num_votes) > 100) {
++ $prog->{q(star-rating)} = [[ sprintf("%.0f / 10", $starsval), "uservotes" ]];
++ }
++ }
++ }
++ }
++ }
++ # restore the previous values
++ $XMLTV::Get_nice::FailOnError = $get_fail;
++ $XMLTV::Get_nice::Delay = $get_delay;
++ }
++
++
++
+ # collect all text lines, we
+ # achive this to jump to the parent first, and walk all the childs until
+ # the anchor is reached
+@@ -1113,11 +1198,15 @@ sub get_infourl_data( $$ ) {
+ # possibilitys
+ # 1: amerikai filmdráma sorozat, 90 perc, 2000, 2. rész
+ # 12 éven aluliak számára ....
++ # added 2004-04-07 :
++ # (ro) Coreea de Sud, 2009, serial de aventuri, episodul 5
+
+ $_ = $part;
+ SWITCH: {
+ if ((m/\s*([0-9\/]+)\. $WORDS{$COUNTRY}->{episode}/) && (! defined $episode))
+ { $episode = $1; last SWITCH;}
++ if ((m/$WORDS{$COUNTRY}->{episode} \s*([0-9\/]+)/) && (! defined $episode))
++ { $episode = $1; last SWITCH;}
+ if ((m/\s*(\d+) $WORDS{$COUNTRY}->{minute}/) && (! defined $minutes))
+ { $minutes = $1; last SWITCH;}
+ if ((m/\s*([12][0-9]{3})/) && (! defined $year))
+@@ -1139,24 +1228,26 @@ sub get_infourl_data( $$ ) {
+ # note: \b(.+): do not match to " író: ", because í is not
+ # part of \b
+
+- if (($_) = $part =~ /^\s*(\S+):/) {
++ # bug #451 [line deleted]
++
++ if (($_) = $part =~ /^\s*(\S+):/) { # does the $line include a ':'
+ # remove the "jobname:" string
+ $part =~ s/^\s*(\S+):\s*//;
+- t "is this a known job?: '$_'"; # e.g.: hu-job
+- if (defined($JOBMAP{$_})) {
+- t "yes, this string is a jobname";
++
++ t "assuming string is a jobname";
+ # this means, we should add our until now collected
+ # person to the credits, and begin to collect new
+ # actors...
+
+ add_person($job, $person, \%credits);
+
+- if (length($JOBMAP{$_})) {
++ t "is this a known job?: '$_'"; # e.g.: hu-job
++ if (defined $JOBMAP{lc($_)} && length($JOBMAP{lc($_)})) {
+ # newly readed part has a en-job (this is defined in DTD, so
+ # this will be the next used job for XML generation
+
+- t "job known in DTD as: $JOBMAP{$_}";
+- $job = $_;
++ t "job known in DTD as: $JOBMAP{lc($_)}";
++ $job = lc($_);
+ $person = $part;
+ } #en-job
+ else {
+@@ -1166,7 +1257,6 @@ sub get_infourl_data( $$ ) {
+ $person = "$_: $part ";
+ } #hu-job
+ next;
+- } #hu-job
+ } #: in the part
+
+ # we are here, if:
+@@ -1200,6 +1290,7 @@ sub get_infourl_data( $$ ) {
+ add_person($job, $person, \%credits) if length($person);
+
+ t "CREDITS: " . d \%credits;
++ $prog->{q(credits)} = \%credits;
+
+ #$prog->{q(category)} = [[ $category, $COUNTRY ]]
+ #if defined $category and length $category;
+@@ -1210,19 +1301,60 @@ sub get_infourl_data( $$ ) {
+ $prog->{q(date)} = $year
+ if defined $year ;
+
++ $prog->{q(episode-num)} = extract_episode( $episode )
++ if defined $episode ;
++
++ $tree->delete;
++}
++
++
++#-------------------------------------------------------------------------------
++# extract_episode
++#-------------------------------------------------------------------------------
++# desc : parse text containing the episode details
++# arguments : 1- episode data
++# returns : xmltv episode-num definition
++#-------------------------------------------------------------------------------
++sub extract_episode( $ ) {
++ my $episode = shift;
++ my ($episode_num, $season);
++
+ if(defined($episode)) {
+ if($episode =~ m#(\d+)/(\d+)#) {
+ # episode-num spec with the total number specified.
++ # swap numbers for port.hu, they have total/num
++ my ($num, $total) = ($1, $2);
++ ($num, $total) = ($2, $1) if ($num > $total);
+ # however XMLTV counts from 0 on ...
+- $prog->{q(episode-num)} = [[ sprintf('%d/%d', $1 - 1, $2), "xmltv_ns" ]];
+- }
+- else {
+- $prog->{q(episode-num)} = [[ $episode, "onscreen" ]];
++ $episode_num = [[ sprintf('. %d/%d .', $num - 1, $total), "xmltv_ns" ], [ $episode, "onscreen" ]];
++
++ } elsif($episode =~ m#([IVX]+)\./(\d+)#) {
++ # patch #80
++ # port.hu style episode numbering: <serie_in_roman>./<episode_in_arabic>. e.g. V./3
++ # episode-num spec with the total number specified.
++ # decode season from roman numeral
++ $season = arabic ($1);
++ # however XMLTV counts from 0 on ...
++ $episode_num = [[ sprintf('%d . %d .', $season - 1, $2 - 1), "xmltv_ns" ], [ $episode, "onscreen" ]];
++
++ } elsif($episode =~ m#(\d+), ([IVX]+)#) {
++ # episode-num spec with the total number specified.
++ # decode season from roman numeral
++ $season = arabic ($2);
++ # however XMLTV counts from 0 on ...
++ $episode_num = [[ sprintf('%d . %d .', $season - 1, $1 - 1), "xmltv_ns" ], [ $episode, "onscreen" ]];
++
++ } elsif($episode =~ m#(\d+)#) {
++ # episode-num spec with just the episode number
++ # however XMLTV counts from 0 on ...
++ $episode_num = [[ sprintf('. %d .', $1 - 1), "xmltv_ns" ], [ $episode, "onscreen" ]];
++
++ } else {
++ $episode_num = [[ $episode, "onscreen" ]];
+ }
+ }
+
+- $prog->{q(credits)} = \%credits;
+- $tree->delete;
++ return $episode_num;
+ }
+
+
+@@ -1241,6 +1373,35 @@ sub grab_icon( $ ) {
+ my $fetchurl = "http://www." . domain() . "/tv/kep_ado/al_".(int(${channelid}) % 10000).".gif";
+ my ($file, $iconurl);
+
++ # that $fetchurl no longer works for RO, so...
++ #test if url is valid
++ $XMLTV::Get_nice::FailOnError = 0;
++ my $image = get_nice($fetchurl);
++ if (!defined $image) {
++ # image url not valid, so we must get it from the programmes page. Ideally we would do that during the main grab but this is a Q&D fix
++ # and I don't want to change too much of this code
++ my $url = "http://www." . domain() . "/pls/w/".($COUNTRY eq 'hu' ? 'old' : '')."tv.channel?i_ch=".$channelid."&i_date=".UnixDate('today','%Y-%m-%d')."&i_where=1";
++
++ my $data=get_nice($url);
++ my $tree = HTML::TreeBuilder->new_from_content($data) or
++ die "could not fetch/parse $url (grab_icon)\n";
++ worker("base-parsing");
++
++ my $body = $tree->look_down("_tag"=>"body");
++ my $container = $body->look_down("_tag" => "div", "class" => qr/main-container-100/);
++ if ($container) {
++ if (my $imgdiv = $container->look_down("_tag" => "div", "style" => qr/float\s*:\s*left/, sub {
++ my $imgtag = $_[0]->look_down('_tag' => 'img');
++ return 0 unless $imgtag;
++ return $imgtag->attr('src') =~ m/http:\/\/media/;
++ } ))
++ {
++ $fetchurl = $imgdiv->look_down('_tag' => 'img')->attr('src');
++ }
++ }
++ }
++ $XMLTV::Get_nice::FailOnError = 1;
++
+ return $fetchurl if ($opt_icons && ! $opt_local_icons);
+
+ # create directory
+@@ -1264,7 +1425,11 @@ sub grab_icon( $ ) {
+ if (open(FILE,">$file")) {
+ t "fetching $fetchurl...";
+ $XMLTV::Get_nice::FailOnError = 0;
+- if (my $image = get_nice($fetchurl)) {
++ #if (my $image = get_nice($fetchurl)) { # now grabbed above
++ if (!$image) {
++ $image = get_nice($fetchurl);
++ }
++ if ($image) {
+ t "icon for $channelid grabbed successfully";
+ print FILE $image;
+ close FILE;
+@@ -1305,7 +1470,7 @@ sub get_channel_urls( $ ) {
+
+ # two sprintf parameters: first: channel_id,, second how many days grabbed
+ my $churlfmt = "http://www." . domain() .
+- "/pls/tv/tv.channel?i_ch=%d&" .
++ "/pls/tv/".($COUNTRY eq 'hu' ? 'old' : '')."tv.channel?i_ch=%d&" .
+ "i_days=1&i_xday=%d&i_where=1";
+
+ # url to grab now (4 days - this is the minimum)
+@@ -1417,9 +1582,9 @@ sub load_configs() {
+ foreach (split( /\n/, $jobmap_str )) {
+ ++ $line_num;
+ tr/\r//d;
+-
+ s/#.*//;
+ next if m/^\s*$/;
++ s/^\s+|\s+$//g; # trim spaces
+
+ $where = "$jobmap_file:$line_num";
+ @fields = split m/:/;
+@@ -1444,6 +1609,7 @@ sub load_configs() {
+ tr/\r//d;
+ s/#.*//;
+ next if m/^\s*$/;
++ s/^\s+|\s+$//g; # trim spaces
+
+ $where = "$catmap_file:$line_num";
+ @fields = split m/:/;
+@@ -1677,7 +1843,7 @@ if ($mode eq 'grab') {
+ my @portids = load_configs();
+
+ # sets %CHANNELS
+- get_channels();
++ get_channels($mode);
+
+ worker("xml-writing");
+ my $writer = new XMLTV::Writer(%w_args);
--- End Message ---