diff options
-rw-r--r-- | HISTORY | 7 | ||||
-rw-r--r-- | eit.c | 54 | ||||
-rw-r--r-- | eit.h | 5 | ||||
-rwxr-xr-x | epg2html.pl | 95 |
4 files changed, 158 insertions, 3 deletions
@@ -311,3 +311,10 @@ Video Disk Recorder Revision History can receive a certain channel on the primary interface. This is currently in an early state and may still cause some problems, but it appears to work nice already. + +2000-11-26: Version 0.69 + +- The EPG data is now dumped into the file /video/epg.data every ten minutes. + Use the Perl script 'epg2html.pl' to convert the raw EPG data into a simple + HTML programme listing. + @@ -13,7 +13,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.c 1.9 2000/11/18 13:42:28 kls Exp $ + * $Id: eit.c 1.10 2000/11/25 12:51:06 kls Exp $ ***************************************************************************/ #include "eit.h" @@ -33,6 +33,8 @@ #include <sys/types.h> #include <time.h> #include <unistd.h> +#include "config.h" +#include "videodir.h" // --- cMJD ------------------------------------------------------------------ @@ -393,6 +395,21 @@ unsigned short cEventInfo::GetServiceID() const return uServiceID; } +/** */ +void cEventInfo::Dump(FILE *f) const +{ + if (tTime + lDuration >= time(NULL)) { + fprintf(f, "E %u %ld %ld\n", uEventID, tTime, lDuration); + if (!isempty(pTitle)) + fprintf(f, "T %s\n", pTitle); + if (!isempty(pSubtitle)) + fprintf(f, "S %s\n", pSubtitle); + if (!isempty(pExtendedDescription)) + fprintf(f, "D %s\n", pExtendedDescription); + fprintf(f, "e\n"); + } +} + // --- cSchedule ------------------------------------------------------------- cSchedule::cSchedule(unsigned short servid) @@ -529,6 +546,19 @@ void cSchedule::Cleanup(time_t tTime) } } +/** */ +void cSchedule::Dump(FILE *f) const +{ + cChannel *channel = Channels.GetByServiceID(uServiceID); + if (channel) + { + fprintf(f, "C %u %s\n", uServiceID, channel->name); + for (cEventInfo *p = Events.First(); p; p = Events.Next(p)) + p->Dump(f); + fprintf(f, "c\n"); + } +} + // --- cSchedules ------------------------------------------------------------ cSchedules::cSchedules() @@ -590,6 +620,13 @@ void cSchedules::Cleanup() } } +/** */ +void cSchedules::Dump(FILE *f) const +{ + for (cSchedule *p = First(); p; p = Next(p)) + p->Dump(f); +} + // --- cEIT ------------------------------------------------------------------ #define DEC(N) dec << setw(N) << setfill(int('0')) @@ -1105,6 +1142,7 @@ void cSIProcessor::Action() unsigned int seclen; unsigned int pid; time_t lastCleanup = time(NULL); + time_t lastDump = time(NULL); struct pollfd pfd; while(true) @@ -1123,6 +1161,19 @@ void cSIProcessor::Action() schedulesMutex.Unlock(); lastCleanup = now; } + if (now - lastDump > 600) + { + LOCK_THREAD; + + schedulesMutex.Lock(); + FILE *f = fopen(AddDirectory(VideoDirectory, "epg.data"), "w"); + if (f) { + schedules->Dump(f); + fclose(f); + } + lastDump = now; + schedulesMutex.Unlock(); + } } /* wait data become ready from the bitfilter */ @@ -1283,4 +1334,3 @@ bool cSIProcessor::RefreshFilters() return ret; } - @@ -13,7 +13,7 @@ * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * - * $Id: eit.h 1.3 2000/11/17 16:14:27 kls Exp $ + * $Id: eit.h 1.4 2000/11/24 14:35:22 kls Exp $ ***************************************************************************/ #ifndef __EIT_H @@ -66,6 +66,7 @@ public: unsigned short GetServiceID(void) const; int GetChannelNumber(void) const { return nChannelNumber; } void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const' + void Dump(FILE *f) const; }; class cSchedule : public cListObject { @@ -92,6 +93,7 @@ public: const cEventInfo *GetEvent(time_t tTime) const; const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); } int NumEvents(void) const { return Events.Count(); } + void Dump(FILE *f) const; }; class cSchedules : public cList<cSchedule> { @@ -107,6 +109,7 @@ public: ~cSchedules(); const cSchedule *GetSchedule(unsigned short servid) const; const cSchedule *GetSchedule(void) const; + void Dump(FILE *f) const; }; typedef struct sip_filter { diff --git a/epg2html.pl b/epg2html.pl new file mode 100755 index 00000000..06d76b74 --- /dev/null +++ b/epg2html.pl @@ -0,0 +1,95 @@ +#!/usr/bin/perl + +# A simple EPG to HTML converter +# +# Converts the EPG data written by 'vdr' into the file /video/epg.data +# into a simple HTML programme listing, consisting of one file per channel +# plus an 'index.htm' file. All output files are written into the current +# directory. +# +# Usage: epg2html.pl < /video/epg.data +# +# See the main source file 'vdr.c' for copyright information and +# how to reach the author. +# +# $Id: epg2html.pl 1.1 2000/11/26 15:23:39 kls Exp $ + +@Index = (); + +sub GetDay +{ + return substr(localtime(shift), 0, 10); +} + +sub GetTime +{ + return substr(localtime(shift), 11, 5); +} + +sub Tags +{ + my $s = shift; + $s =~ s/\&/&/g; + $s =~ s/</</g; + $s =~ s/>/>/g; + return $s; +} + +while (<>) { + chomp; + if (/^C ([^ ]+) *(.*)/) { + my $Channel = $2; + (my $Page = $Channel) =~ s/ /_/g; + $Channel = Tags($Channel); + push(@Index, qq{<a href="$Page.htm">$Channel</a><br>\n}); + my %Events = (); + while (<>) { + if (/^E (.*) (.*) (.*)/) { + (my $Time, $Duration) = ($2, $3); + my $Title = "", $Subtitle = "", $Description = ""; + while (<>) { + if (/^T (.*)/) { $Title = Tags($1); } + elsif (/^S (.*)/) { $Subtitle = Tags($1); } + elsif (/^D (.*)/) { $Description = Tags($1); } + elsif (/^e/) { + $Events{$Time} = [($Duration, $Title, $Subtitle, $Description)]; + last; + } + } + } + elsif (/^c/) { + my @Schedule = (); + my $Day = ""; + for $t (sort keys %Events) { + (my $Duration, $Title, $Subtitle, $Description) = @{$Events{$t}}; + my $d = GetDay($t); + if ($d ne $Day) { + push(@Schedule, "</table>\n") if ($Day && @Schedule); + push(@Schedule, "<h2>$d</h2>\n"); + push(@Schedule, "<table cellspacing=2>\n"); + $Day = $d; + } + my $Entry = $Title; + $Entry .= "<br><i>$Subtitle</i>" if $Subtitle; + $Entry .= "<br>$Description" if $Description; + push(@Schedule, "<tr><td valign=top>" . GetTime($t) . "</td><td>$Entry</td></tr>\n"); + } + push(@Schedule, "</table>\n") if (@Schedule); + open(PAGE, ">$Page.htm") or die $!; + print PAGE "<html>\n<head><title>$Channel</title><head>\n<body>\n"; + print PAGE "<h1>$Channel</h1>\n"; + print PAGE @Schedule; + print PAGE "</body>\n</html>\n"; + close(PAGE); + last; + } + } + } + } + +open(INDEX, ">index.htm") or die $!; +print INDEX "<html>\n<head><title>EPG Index</title><head>\n<body>\n"; +print INDEX sort { lc($a) cmp lc($b) } @Index; +print INDEX "</body>\n</html>\n"; +close(INDEX); + |