#!/usr/bin/ruby -w autoload :XMLTV, 'xmltv/xmltv' module XMLTV class RtGrabber < Grabber Fields = %w{ title sub_title episode date director cast premiere film repeat subtitles widescreen new_series deaf_signed black_and_white star_rating certificate category desc choice datum start stop duration_mins } TimeDiff = 60 * 60 EncodingErrors = { /\303[\306\346\341]/ => "'", /\310\355/ => "\303\241", /\310\321/ => "\303\245" } def version [ "RtGrabber 0.9", super].join("\n") end def base_url 'http://xmltv.radiotimes.com/xmltv' end def fetch_all_channels chn = open("#{base_url}/channels.dat") {|h| h.readlines } channels = Hash.new chn.each do |c| chan_id, name = c.chomp.split('|') channels[chan_id] = name end save_object(channels, channel_list) channels end def lang 'en' end ### Must Implement def grab_channel(chan_id) uri = "#{base_url}/#{chan_id}.dat" # uri = '/home/han/47.dat' # uri = '/var/tmp/xmltv/102.dat' info = open(uri) {|h| h.readlines }.map{|x| x.chomp} @hits += 1 @channel_info = Array.new info.each do |program| begin prog = program.split('~') entry = Hash.new Fields.each_with_index do |el, i | item = prog[i] next if item == 'false' || item.empty? begin entry[el] = item.ck_utf rescue Iconv::IllegalSequence => e ret = false EncodingErrors.each_pair do |k, v| # STDERR.puts "Try: #{k.dump} #{v}\n#{item.dump}\n" if item.gsub!(k, v) # STDERR.puts "====> #{item.dump}\n" ret = true break end # STDERR.puts 'failed' end retry if ret prt = (e.failed =~ /[[:print:]]/) failstring = e.failed[0 ... prt] STDERR.puts "Repl: #{failstring.dump}" EncodingErrors[failstring] = '?' retry if item.gsub!(e.failed[0 ... prt], '?') raise "Encoding error: #{e.failed}\n" end end # puts entry['cast'], entry['start'], entry['stop'] @channel_info << entry rescue StandardError => exc STDERR.puts exc.class, exc.message, exc.backtrace PP.pp prog, STDERR raise end end info.size end def transform(chan_id) progdata_array = Array.new @channel_info.each do |p| progdata_array << ( progdata = proghash(p, chan_id)) dag, maand, jaar = p['datum'].scan(/\d+/).map{|x| x.to_i} startuur, startmin = p['start'].scan(/\d+/).map{|x| x.to_i} stopuur, stopmin = p['stop'].scan(/\d+/).map{|x| x.to_i} progdata['start'] = Time.local(jaar, maand, dag, startuur, startmin) + TimeDiff date_stats(chan_id, progdata['start']) progdata['stop'] = Time.local(jaar, maand, dag, stopuur, stopmin) + TimeDiff progdata['stop'] += Dag if progdata['stop'] < progdata['start'] progdata['credits']['director'] = p['director'] if p['director'] progdata['video']['colour'] = 'no' if p['black_and_white'] progdata['video']['aspect'] = '16:9' if p['widescreen'] progdata['sub-title'] = p['episode'] || p['sub_title'] || '' progdata['category'] = 'Film' if p['film'] progdata['subtitles']['type'] = 'teletext' if p['subtitles'] progdata['star-rating']['value'] = "#{p['star_rating']}/5" if p['star_rating'] if (cast = p['cast']) cast = cast.split("\r")[0] progdata['credits']['actor'] = blob = cast.index('|') ? cast.split('|').map {|x| x.gsub(/^.*[*]/,'') } : cast.split(',') end %w{ widescreen black_and_white }.each do |it| # STDERR.puts "#{it}: #{p[it]}" end # pp progdata # pp p end progdata_array end end end XMLTV::RtGrabber.new.run