Listing data is transfered between modules as an ordered set of five-tuples, in the following format:

[channel] [start time] [end time] [title] [description]

Time values are on the form YYYYMMDDHHMMSS TIMEZONE.


TV320030503182500 CEST20030503185000 CESTSimpsonsAmerikansk tecknad komediserie.[9782262]

It is not unusual that shows lack a description, so the case when description is undefined must be handled by the applications involved.

The flow of listing data

If you are going to develop stuff in the Televinken framework, it might be useful to know what files are involved where. In the following figure, the components to the left of the dashed line represents the programs you execute. The others are part of the "inner workings" of Televinken.

diagram describing the flow of listing data

The import utility, will ask every import module it knows about what channels it knows about, and import those. Overlaps (for example both and knows how to fetch SVT1) are dealt with by just accepting the first successful import. If an import fails, the next one that knows about the channel we are trying to fetch will be asked.

When done, will write the listing to storage via This is actually just a wrapper around one or more of the storage modules. This approach has two advantages I can think of; First, I don't have to rewrite every cgi script if I should want to change storage system. Secondly, I can use several storage modules for different purposes. The default configuration is to use the storage module for storing and fetching, but also use for just storage.

That should have explained and, and to some extent import_modules/* and storage_modules/*. What else is hidden in the tarball?

Scripts that will output lots of HTML if treated correctly. The user-end of Televinken.
A collection of utility functions for the cgi programs. Time conversion, movie guess, html code several pages has in common etc.
The routines that deal with user settings for the cgi programs. If you are looking for the default values, this is where to look. This is also the cookie-monster of the system.

The import modules talks to the import modules, in the cleverly named directory import_modules/.

Each import module implements the following:

Your everyday constructor.
A function that returns an array with the name of all channels this module knows how to import.
Given a channel name, returns (one of) the url(s) that will be used to get listing data.
Given a channel name, fetch the listing data and return it in the format defined earlier.

When I started gathering listings for several days ahead, some changes where made. Each module that knows how to get listings for several day must have a sub named multiple_dates, and fetchchannel is then fetchchannel($channel, $date) (with $date on the form YYYY-MM-DD).

If you want to create your own import module, I recommend using one of the current as a skeleton. A usually start with import_modules/ when I write a new one. I usually go through these steps:

So far, only one source use HTTP POST instead of HTTP GET. Check import_modules/ if you need an example.


All scripts will talk to, which is a wrapper for one or more storage modules. These modules implement the following:

Stores a hash, (channel name -> url) in some way.
Builds a hash as above, and returns it.
Gets an array of listing data (format as above) and stores it in some way.
Takes an array of channels, a start time and an end time. Returns the corresponding tv listing data.