⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getskyepg.pl

📁 These files contain the source code of the "Video Disk Recorder", which is based on the DVB driver
💻 PL
字号:
#!/usr/bin/perl# getskyepg.pl: Get EPG data for Sky channels from the Internet## Connects to a running VDR instance via SVDRP, gets the channel data# for the Sky channels and connects to Internet web pages to extract the# EPG data for these channels. The result is sent to VDR via SVDRP.## See the README file for copyright information and how to reach the author.## $Id: getskyepg.pl 1.6 2006/12/02 09:52:49 kls Exp $use Getopt::Std;use Time::Local;$Usage = qq{Usage: $0 [options]Options: -c filename        channel config file name (default: channels.conf.sky)         -d hostname        destination hostname (default: localhost)         -p port            SVDRP port number (default: 2001)         -S source          channel source (default: S28.2E)         -D days            days to get EPG for (1..7, default: 2)         -U                 use this if your version of 'wget' doesn't support -U};die $Usage if (!getopts("c:d:D:hp:S:U") || $opt_h);$Conf   = $opt_c || "channels.conf.sky";$Dest   = $opt_d || "localhost";$Port   = $opt_p || 2001;$Source = $opt_S || "S28.2E";$Days   = $opt_D || 2;$User   = $opt_U;# See "Rules for using this data" on http://bleb.org/tv/data/listings.# In case you modify this script in a way that changes its behavior# towards the www.bleb.org website, please replace 'vdrbugs@cadsoft.de'# with your own email address! That way Andrew Flegg <andrew@bleb.org>,# who runs that web site, can contact you in case of problems.$IDENT = "VDR::getskyepg.pl, http://www.cadsoft.de/vdr - vdrbugs\@cadsoft.de";$GAP = 2;$SkyWebPage = "www.bleb.org/tv/data/listings";$WGET = "/usr/bin/wget -q -O-";$WGET .= " -U '$IDENT'" unless $User;$LOGGER = "/usr/bin/logger -t SKYEPG";$DST = -3600; # Daylight Saving Time offset$SecsInDay = 86400;@Channels = ();$idxSource = 0;$idxNumber = 1;$idxName = 2;Error("days out of range: $Days") unless (1 <= $Days && $Days <= 7);sub Log{  system("$LOGGER '@_'");}sub Error{  Log(@_);  die "$0: @_\n";}sub GetChannels{  open(CHANNELS, $Conf) || Error("$Conf: $!");  while (<CHANNELS>) {        chomp;        next if (/^#/);        my @a = split(":");        push(@Channels, [@a]) unless ($a[$idxName] eq "x");        }  close(CHANNELS);}GetChannels();sub GetPage{  my $channel = shift;  my $day = shift;  $day--;  my $url = "http://$SkyWebPage/$day/$channel.xml";  $url .= "?$IDENT" if $User;  Log("reading $url");  my @page = split("\n", `$WGET '$url'`);  Log("received " . ($#page + 1) . " lines");  return @page;}sub ReplaceTags{  my $s = shift;  $s =~ s/&amp;/&/g;  return $s;}sub StripWhitespace{  my $s = shift;  $s =~ s/\s*(.*)\s*/$1/;  $s =~ s/\s+/ /g;  return $s;}sub Extract{  my $s = shift;  my $t = shift;  $s =~ /<$t>([^<]*)<\/$t>/;  return ReplaceTags(StripWhitespace($1));}# In order to get the duration we need to buffer the last event:$Id = "";$Time = 0;$Title = "";$Subtitle = "";$Desc = "";sub GetEpgData{  my ($channel, $channelID) = @_;  my $numEvents = 0;  SVDRPsend("C $channelID");  $Time = 0;  for $day (1 .. $Days) {      my $dt = 0;      my @page = GetPage($channel, $day);      my $data = "";      for $line (@page) {          chomp($line);          if ($line =~ /<programme>/) {             $data = "";             }          elsif ($line =~ /<\/programme>/) {             my $title = Extract($data, "title");             my $subtitle = Extract($data, "subtitle");             my $desc = Extract($data, "desc");             my $start = Extract($data, "start");             # 'end' is useless, because it is sometimes missing :-(             # my $end = Extract($data, "end");             if (!$subtitle) {                # They sometimes write all info into the description, as in                # Episode: some description.                # Why don't they just fill in the data correctly?                my ($s, $d) = ($desc =~ /([^:]*)[:](.*)/);                if ($s && $d) {                   $subtitle = $s;                   $desc = $d;                   }                }             # 'start' and 'end' as time of day isn't of much use here, since             # the page for one day contains data that actually belongs to the             # next day (after midnight). Oh well, lets reconstruct the missing             # information:             $start = "0" . $start if (length($start) < 4);             my ($h, $m) = ($start =~ /(..)(..)/);             $dt = $SecsInDay if ($h > 12);             # convert to time_t:             my @gmt = gmtime;             $gmt[0] = 0;  # seconds             $gmt[1] = $m; # minutes             $gmt[2] = $h; # hours             $time = timegm(@gmt) + ($day - 1) * $SecsInDay + ($h < 12 ? $dt : 0);             # compensate for DST:             $time += $DST if (localtime($time))[8];             # create EPG data:             if ($Time) {                $duration = $time - $Time;                SVDRPsend("E $Id $Time $duration");                SVDRPsend("T $Title");                SVDRPsend("S $Subtitle");                SVDRPsend("D $Desc");                SVDRPsend("e");                $numEvents++;                }             # buffer the last event:             $Id = $time / 60 % 0xFFFF; # this gives us unique ids for every minute of over 6 weeks             $Time = $time;             $Title = $title;             $Subtitle = $subtitle;             $Desc = $desc;             }          else {             $data .= $line;             }          }      sleep($GAP);      }  SVDRPsend("c");  Log("generated $numEvents EPG events");}sub ProcessEpg{  for (@Channels) {      my $channel = @$_[$idxName];      my $channelID = @$_[$idxSource];      Log("processing channel $channel - $channelID");      SVDRPsend("PUTE");      SVDRPreceive(354);      GetEpgData($channel, $channelID);      SVDRPsend(".");      SVDRPreceive(250);      }  Log("done");}#---------------------------------------------------------------------------# TODO: make this a Perl module??? What about Error()???use Socket;$Timeout = 300; # max. seconds to wait for response$SIG{ALRM} = sub { Error("timeout"); };alarm($Timeout);$iaddr = inet_aton($Dest)                   || Error("no host: $Dest");$paddr = sockaddr_in($Port, $iaddr);$proto = getprotobyname('tcp');socket(SOCK, PF_INET, SOCK_STREAM, $proto)  || Error("socket: $!");connect(SOCK, $paddr)                       || Error("connect: $!");select(SOCK); $| = 1;SVDRPreceive(220);ProcessEpg();SVDRPsend("QUIT");sub SVDRPsend{  my $s = shift;  print SOCK "$s\r\n";}sub SVDRPreceive{  my $expect = shift | 0;  my @a = ();  while (<SOCK>) {        s/\s*$//; # 'chomp' wouldn't work with "\r\n"        push(@a, $_);        if (substr($_, 3, 1) ne "-") {           my $code = substr($_, 0, 3);           Error("expected SVDRP code $expect, but received $code") if ($code != $expect);           last;           }        }  return @a;}#---------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -