Use TopfieldUSBEcode for received values too.
[MacTF.git] / dat2tgd.pl
blob210e3be49bd790952aa8a9d9afe87ae20b9f44c8
1 #!/usr/bin/perl -s
3 # Convert .dat files to tgd format
4 # Nigel Whitfield, 2005
5 # With thanks to the rt grabber code, from XMLTV
7 # 0.4 added purge of output folder, new channelmap.ini options
8 # 0.3 added -days switch
9 # 0.2 added -oldtgd switch
10 # 0.1 original version
12 # either specify channels on command line, or use channelmap.ini
13 # command line channel names use the same names as in channelmap.ini
14 # eg dat2tgd.pl more4 e4 sky3
15 # -verbose switch lets you see what's happening
16 # -oldtgd switch creates older TGD format files
17 # -days switch limits number of days
18 # eg dat2tgd.pl -verbose -oldtgd -days 3 more4 e4
20 # start by purging old files from the output folder
21 # override this with the -nopurge switch
23 if ( ! $nopurge ) {
25 @today = localtime(time) ;
26 $todaysname = ($today[5] +1900)*10000 + ($today[4]+1)*100 + $today[3] ;
28 foreach $tgd (<output/*.tgd>) {
30 if (($tgd =~ /(2[0-9]*).tgd/) && ($1 < $todaysname )) {
31 $verbose && print "Found stale tgd file $tgd\n" ;
32 unlink($tgd) ;
38 $startup = time() ;
40 # is the days switch given?
41 # $limit is the default number of days; use 0 for all available
43 $limit = 0 ;
45 if ( $days ) {
46 $limit = $ARGV[0] ;
47 shift(@ARGV) ;
49 $verbose && print "Limiting to $limit days\n." ;
52 if ( $limit > 0 ) {
53 # Now work out when the last date required is
54 ($le_day, $le_month, $le_year) = &date_limit($limit) ;
56 $verbose && print "Last EPG date is $le_day/$le_month/$le_year\n" ;
59 # do the same for the last extended info date, if given
60 # you can specify this using the -extended N option, eg
61 # dat2tgd.pl -extended 3
63 if ( $extended ) {
64 $extlimit = $ARGV[0] ;
65 shift(@ARGV) ;
67 $verbose && print "Limiting extended information to $extlimit days\n" ;
69 ($lx_day, $lx_month, $lx_year) = &date_limit($extlimit) ;
71 $verbose && print "Last date for extended info is $lx_day/$lx_month/$lx_year\n" ;
75 if ( $ARGV[0] eq '' ) {
78 # read channelmap.ini to find out which channels to process
79 # v0.4 = channels can now have options for the amount of information in each one
81 open( MAP, 'channelmap.ini' ) || die("Unable to open channelmap.ini\n") ;
83 while(<MAP>) {
85 next if /^#/ ;
87 ($channel, $rtid, $chanopts) = split(/\s+/) ;
89 if ( $chanopts ) {
91 # process individual channel options
93 foreach $chopt (split(',',$chanopts)) {
94 ($opt,$val) = split('=',$chopt) ;
96 $channeloptions{$channel . '-' . $opt} = $val ;
100 if ( ! -e "channels/$channel.dat" ) {
101 print "Skipping $channel - no dat file\n" ;
102 } else {
103 push ( @channels, $channel ) ;
107 close MAP ;
108 } else {
110 # use a list of channels from the command line
112 foreach $channel ( @ARGV ) {
113 if ( ! -e "channels/$channel.dat" ) {
114 print "Skipping $channel - no dat file\n" ;
115 } else {
116 push ( @channels, $channel ) ;
121 # now the channels array has all the channels we're going to
122 # build TGD files for
124 $verbose && print "Building epg for @channels\n" ;
126 # we'll build up the EPG data in an array
127 # the key to the array is the date of broadcast
129 foreach $channel ( @channels ) {
131 $verbose && print "Processing dat file for $channel\n" ;
133 # check channel specific options
135 if ($channeloptions{$channel . '-days'}) {
136 ( $l_day, $l_month, $l_year ) = &date_limit($channeloptions{$channel . '-days'}) ;
137 $verbose && print "Last EPG date $is $l_day/$l_month/$l_year\n" ;
140 if ($channeloptions{$channel . '-ext'}) {
141 ( $x_day, $x_month, $x_year) = &date_limit($channeloptions{$channel . '-ext'}) ;
142 $verbose && print "Limiting extended info to $x_day/$x_month/$x_year\n" ;
145 if ($channeloptions{$channel . '-genres'}) {
146 $verbose && print "Limiting extended info to genres matching $channeloptions{$channel . '-genres'}\n" ;
149 if ($channeloptions{$channel . '-except'}) {
150 $verbose && print "Omitting extended info for genres matching $channeloptions{$channel . '-except'}\n" ;
154 if ($channeloptions{$channel . '-hours'}) {
155 $verbose && print "Including only programmes between $channeloptions{$channel . '-hours'}\n" ;
158 if ($channeloptions{$channel . '-omit'}) {
159 $verbose && print "Omitting programmes between $channeloptions{$channel . '-omit'}\n" ;
162 open( DATFILE, "channels/$channel.dat" ) || die ("Can't open dat file for $channel\n" ) ;
164 while(<DATFILE>) {
166 # code shamelessly modelled on the RT grabber code
168 s/&#8212;/--/g;
169 s/&#8230;/.../g;
170 tr/\207\211\200\224/\347\311\055\055/;
172 @epgentry = split/\~/ ;
174 # a basic sanity check
175 next if (@epgentry != 23 ) ;
177 my ( $title, $subtitle, $episode, $yearmade, $director, $cast,
178 $premier, $film, $repeat, $subtitles, $widescreen, $new,
179 $signed, $bw, $rating, $cert, $genre, $description, $choice,
180 $date, $starttime, $endtime, $duration ) = @epgentry ;
182 # date and time checks and limits
184 ( $day, $month, $year ) = split('/', $date) ;
185 ( $sh, $sm ) = split(':', $starttime) ;
186 ( $eh, $em ) = split(':', $endtime) ;
188 # check global limit on number of days
189 if ( $limit > 0 ) {
190 next if ( $year > $le_year ) ;
191 next if (( $month > $le_month ) && ( $year == $le_year )) ;
192 next if (( $day > $le_day ) && ( $month == $le_month )) ;
196 # check per channel limit on number of days
197 if ($channeloptions{$channel . '-days'}) {
198 next if ( $year > $l_year ) ;
199 next if (( $month > $l_month ) && ( $year == $l_year )) ;
200 next if (( $day > $l_day ) && ( $month == $l_month )) ;
203 # check per channel limit on times to omit or include
204 if ($channeloptions{$channel . '-omit'}) {
205 ( $earliest, $latest ) = split(/-/, $channeloptions{$channel . '-omit'}) ;
206 $begin = $sh*100 + $sm ;
207 next if (( $begin >= $earliest ) && ( $begin < $latest )) ;
210 if ($channeloptions{$channel . '-hours'}) {
211 ( $earliest, $latest ) = split(/-/, $channeloptions{$channel . '-hours'}) ;
212 ( $latest == '0000' ) && ( $latest = '2400' ) ;
214 $begin = $sh*100 + $sm ;
215 next if (( $begin < $earliest ) || ( $begin >= $latest )) ;
219 # we're making at least a standard EPG entry
220 $events++ ;
222 # date and time conversions
224 if ( $eh < $sh ) {
225 $eh = $eh + 24 ;
228 $begin = 60 * $sh + $sm ;
229 $end = 60 * $eh + $em ;
231 $runtime = $end - $begin ;
233 $tgdfile = $year . $month . $day ;
235 if ( $lasttgd ne $tgdfile ) {
236 $verbose && print '.' ;
237 $lasttgd = $tgdfile ;
240 # now decide what goes where
242 if ( $episode ne '' ) {
243 $shortinfo = $episode ;
244 } else {
245 $shortinfo = $subtitle ;
248 if ( $shortinfo eq '' ) {
249 $shortinfo = '[' . $genre . ']' ;
250 } else {
251 $shortinfo .= ' [' . $genre . ']' ;
254 if ( $genre eq 'Film' ) {
255 $shortinfo .= " $director, $yearmade." ;
258 if ( $new eq 'true' ) { $shortinfo .= ' [New]' ; }
259 if ( $repeat eq 'true' ) { $shortinfo .= ' [Repeat]' ; }
261 # now the long description
263 $longinfo = $description ;
265 ( $yearmade ne '' ) && ( $longinfo .= " $yearmade." ) ;
266 ( $director ne '' ) && ( $longinfo .= " Directed by $director." ) ;
267 ( $signed eq 'true' ) && ( $longinfo .= ' Signed.' ) ;
268 ( $bw eq 'true' ) && ( $longinfo .= ' Black & white.' ) ;
270 # throw it away if it's not needed
272 if ( $extended ) {
274 if (( $year > $lx_year ) ||
275 (( $month > $lx_month ) && ( $year == $lx_year )) ||
276 (( $day > $lx_day ) && ( $month == $lx_month ))) {
277 $longinfo = '' ;
281 # channel specific date check
283 if (($channeloptions{$channel . '-ext'}) && ( $longinfo ne '')) {
285 if (( $year > $x_year ) ||
286 (( $month > $x_month ) && ( $year == $x_year )) ||
287 (( $day > $x_day ) && ( $month == $x_month ))) {
288 $longinfo = '' ;
293 # channel specific genre checks
295 if (($channeloptions{$channel . '-genres'}) && ($longinfo ne '')) {
296 if ( $genre !~ /$channeloptions{$channel . '-genres'}/i ) {
297 $longinfo = '' ;
302 if (($channeloptions{$channel . '-except'}) && ($longinfo ne '')) {
303 if ( $genre =~ /$channeloptions{$channel . '-except'}/i ) {
304 $longinfo = '' ;
309 ( $longinfo ne '' ) && $extinfo++ ;
312 # this is our TGD info line
314 if ( $oldtgd ) {
315 $tgd = "$channel\t$year-$month-$day $sh:$sm\t$runtime\t$title\t$shortinfo\t$longinfo\t\tN\r\n" ;
316 } else {
317 $tgd = "$channel\t$year/$month/$day $sh:$sm\t$runtime\t$title\t$shortinfo\t$longinfo\t\t\t\r\n" ;
320 $epgdata{$tgdfile} .= $tgd ;
324 $verbose && print "$channel complete\n" ;
327 # now all the TGD data is in memory, in the epgdata array
328 # we can create output files, one per day
330 foreach $dayfile ( keys %epgdata ) {
332 $verbose && print "Generating TGD file $dayfile\n" ;
334 open( TGD, "> output/$dayfile.tgd" ) || die("Can't create TGD $dayfile\n") ;
336 print TGD $epgdata{$dayfile} ;
337 close TGD ;
340 # report totals
342 $verbose && print "Created $events EPG entries, $extinfo extended information entries\n" ;
344 exit ;
346 sub date_limit {
348 local ($days) = @_ ;
349 local (@lastepg) ;
351 @lastepg = localtime($startup+60*60*24*($days-1)) ;
353 return ( $lastepg[3], $lastepg[4] + 1, $lastepg[5] + 1900 ) ;