From f1d1c9849c8e27cccb46cf9c0d0ccb59da3f91f9 Mon Sep 17 00:00:00 2001 From: Klaus Schmidinger Date: Mon, 6 Aug 2001 18:00:00 +0200 Subject: Version 0.90 - Modified the display of the channel group separators (thanks to Markus Lang for this suggestion). - Added support for replaying DVDs (thanks to Andreas Schultz). See INSTALL for instructions on how to compile VDR with DVD support. - Fixed replay progress display in case replay is paused while watching an ongoing recording. - Ringbuffer uses semaphores to signal empty/full conditions. - Fixed calculating the timeout value in cFile::FileReady() (thanks to Wolfgang Henselmann-Weiss). --- Tools/master-timer/LIESMICH | 106 +++ Tools/master-timer/README | 52 ++ Tools/master-timer/Todo | 10 + Tools/master-timer/master-timer.pl | 1169 ++++++++++++++++++++++++++++ Tools/master-timer/process_summary.pl | 79 ++ Tools/master-timer/sample/channels-to-scan | 8 + Tools/master-timer/sample/config | 14 + Tools/master-timer/sample/deepblack | 79 ++ Tools/master-timer/sample/done | 1 + Tools/master-timer/sample/subtitle-movie | 41 + Tools/master-timer/sample/torecord | 32 + Tools/master-timer/scan-channels | 8 + 12 files changed, 1599 insertions(+) create mode 100644 Tools/master-timer/LIESMICH create mode 100644 Tools/master-timer/README create mode 100644 Tools/master-timer/Todo create mode 100755 Tools/master-timer/master-timer.pl create mode 100755 Tools/master-timer/process_summary.pl create mode 100644 Tools/master-timer/sample/channels-to-scan create mode 100644 Tools/master-timer/sample/config create mode 100644 Tools/master-timer/sample/deepblack create mode 100644 Tools/master-timer/sample/done create mode 100644 Tools/master-timer/sample/subtitle-movie create mode 100644 Tools/master-timer/sample/torecord create mode 100755 Tools/master-timer/scan-channels (limited to 'Tools/master-timer') diff --git a/Tools/master-timer/LIESMICH b/Tools/master-timer/LIESMICH new file mode 100644 index 0000000..9694875 --- /dev/null +++ b/Tools/master-timer/LIESMICH @@ -0,0 +1,106 @@ + Master-Timer + ============ + + +1. Einleitung +------------- + +Master-Timer ist ein System zum automatischen Aufnehmen von Serien und Filmen. + +2. Voraussetzungen +------------------ + +VDR liefert die "epg.data". + +3. Konfigurationsdateien +------------------------ + +Alle Konfigurationsdateien liegen unter ".master-timer" + +config: Eine Ansammlung von Key-Value Paaren. Alle sind "optional" und + erhalten dann die angegebenen Default-Werte + +(# = Kommentarzeilen) +marginstart (Default 600) + Anzahl der "Sicherheits" Sekunden die ein Timer frueher beginnen soll + +marginstop (Default 600) + Anzahl der "Sicherheits" Sekunden die ein Timer laenger dauern soll + +defaultprio (Default 50) + Die Prioritaet die fuer Timer verwendet wird wo keine Prioritaet + angegeben ist + +DVBCards (Default 1) + Anzahl der vorhandenen DVB-Karten (Derzeit nicht verwendet) + +Dest-Host (Default "localhost") + Host-name oder IP des Rechners auf dem VDR laeuft + +Dest-Port (Default "2001") + Port der VDR verwendet + +jointimers (Default 0) + Sollen aufeinanderfolgende Timer auf den gleichen Kanal zusammengefasst + werden (0 = "Nein", alles andere "Ja") + +debug (Default 0) + Debug-Level, die einzelnen Debug-Werte muessen aus folgenden Werten + zusammengezaehlt werden + 1 : Dump "torecord" + 2 : Dump all timers + 4 : Show when a timer will be deleted + 8 : Dump the "Done" REs + 16 : Verbose Config-Reading + +deepblack: Eine Liste von Titeln die man NIEMALS NIMMER sehen will + Jede Zeile = 1 Titel + +subtitle-movies: Eine Liste der "Subtitel" die ein Zeichen fuer einen Film sind + (Soweit die von den Sendern richtig ausgefuellt sind.) + Jede Zeile = 1 Subtitel + +torecord: Die Sachen die man Aufnehmen will + Jede Zeile = 1 Timer +# Format: (Every field is "optional". +# [Title RE|Subtitle RE|Description RE|Channel-Name|Timeframe|Prio|Timer-Title] +# +# To record something at least one of the "Title", "Subtitle" or "Description" +# Fields has to be provided. This 3 fields are "include" and the rest are +# "exclude" fields! +# +# More than one channel definition can be provided. The delimiter is ";" +# Additionaly you can make a "blacklist" of Channels when you prepent a "!" to the first Channel Definition +# The "!" is only tested for the FIRST Channel definition. +# You can only have a white or a blacklist (Mixing doesn't make sense!) +# +# ex. Record the series "Deep Space Nine" on Sci-Fantasy in the timeframe 09:00 - 14:00 +# Deep Space Nine|||Sci-Fantasy|0900-1400|99|DS9 +# +# Record all "Actionfilm"s with "Schwarzenegger" +# |Actionfilm|Schwarzenegger +# + + +done: The titles/subtitles which are already recorded/should not be recorded + (Programmed Timers which got inserted into "done" will be deleted + automaticaly) + +4. Notices +---------- + +- Recordings "overlapping" on the same channel, will be joined into one Timer +- Title/Subtitle/Descriptions are "fixed" for Channel that don't fill them + out "correctly" (Currently the "Bugs" from Pro-7/VOX/VIVA) + Pro7: Remove the Title from the Subtitle ' / <Subtitle>' + VOX/VIVA: Subtitle is enclosed into "" and after ". " is the description + VIVA: When the Subtitle beginns with space the subtitle is moved to + description + All (except the second VIVA one) fixes are tried onto ALL Subtitles. + +5. Known-Bugs +------------- + +- It isn't checked if there are enough DVB-Cards +- Overlapping Timers, on the same channel, are always joined +- JOINed timers which are "done" don't get deleted automaticaly diff --git a/Tools/master-timer/README b/Tools/master-timer/README new file mode 100644 index 0000000..c71e6e1 --- /dev/null +++ b/Tools/master-timer/README @@ -0,0 +1,52 @@ + Master-Timer (w) by Matthias Schniedermeyer (ms@citd.de) + ============ + + +1. Introduction +--------------- + +Master-Timer ist a system for recording Films/Series automaticaly + +2. Requierements +---------------- + +epg.data + +3. Config-Files +--------------- + +For all files: One Entry per Line. Each line is a "Regular Expresion" + So you can use all Perl-Style REs you want. + The RE are matched with "i" so they are case insensitive! + (Except for the "done"-list, these must match excatly!) + +deepblack: Blacklist of "Titles" you NEVER EVER want to get to you eyes + +subtitle-movies: A list of "Subtitles" which indicate a movie. + (For Channels that correctly fill out the Subtitle. + e.g. it won't work for *eRTL*) + +torecord: The titles/subtitles/Description you want to record + +done: The titles/subtitles which are already recorded/should not be recorded + (Programmed Timers which got inserted into "done" will be deleted + automaticaly) + +4. Notices +---------- + +- Recordings "overlapping" on the same channel, will be joined into one Timer +- Title/Subtitle/Descriptions are "fixed" for Channel that don't fill them + out "correctly" (Currently the "Bugs" from Pro-7/VOX/VIVA) + Pro7: Remove the Title from the Subtitle '<Title> / <Subtitle>' + VOX/VIVA: Subtitle is enclosed into "" and after ". " is the description + VIVA: When the Subtitle beginns with space the subtitle is moved to + description + All (except the second VIVA one) fixes are tried onto ALL Subtitles. + +5. Known-Bugs +------------- + +- It isn't checked if there are enough DVB-Cards +- Overlapping Timers, on the same channel, are always joined +- JOINed timers which are "done" don't get deleted automaticaly diff --git a/Tools/master-timer/Todo b/Tools/master-timer/Todo new file mode 100644 index 0000000..722ee96 --- /dev/null +++ b/Tools/master-timer/Todo @@ -0,0 +1,10 @@ + +- "Intelligenter" Kanal-Scanner (z.B. nur 1 Kanal fuer ein + Sender-"Gruppe") +- Filtern nach Serie/Film +- "Komfortable" Anzeige, mit Black & Whitelisten, fuer Genres/Titeln usw. +- Unterstueztung von 1xVDR pro Karte +- Abspielen (mit automatischen "killen" des "Frontend"-VDRs) von + Aufzeichnungen +- "View"-Timer d.h. Timer der nicht Aufnimmt sondern nur den Kanal aendert +- "unwichtige" Timer "verdraengen" wenn andere Aufnahmen anstehen. diff --git a/Tools/master-timer/master-timer.pl b/Tools/master-timer/master-timer.pl new file mode 100755 index 0000000..3b98acc --- /dev/null +++ b/Tools/master-timer/master-timer.pl @@ -0,0 +1,1169 @@ +#!/usr/bin/perl -w + +use strict; +# For the TCP-Connection to VDR +use Socket; +# For converting the Timers, read from VDR, back to Unix-Timestamps +use Time::Local; + +# Debugmode +# You have to add the following numbers to build the debug-var +# 1 : Dump the "torecord" +# 2 : Dump all timers +# 4 : Show when a timer will be deleted +# 8 : Dump the "Done" REs +# 16 : Verbose Config-Reading +my $debug = 0; + +# The Supervariable Program +# %Program{$title}{$channel}{$time}{duration} +# {subtitle} +# {description} + +# The Supervariable Timer +# %Timer{$time}{$channel}{$title}{duration} +# {subtitle} +# {prio} +# {real_title} +# {VDR} (Already programmed) +# The Value of VDR is ">0" for the position in the Timer-List or "R" for a "Repeating" Timer. +# A Value of >1.000.000 is a Master Timer-Timer which is already programmed into VDR + +# Variable-Definition +my (%Program, @channels, %channels, %Timer); + +# Which Subtitles are Movies +my ($subtitle_movie); + +# Blacklist +my ($title_deepblack); + +# What is already recorded/Should not be recorded +my ($title_done, $subtitle_done); + +# What to record +my ($title_torecord, $subtitle_torecord, $description_torecord, @title_torecord, @subtitle_torecord, @description_torecord, @channel_torecord, @timeframe_torecord, @prio_torecord, @timer_title_torecord, $num_torecord, @marginstart_torecord, @marginstop_torecord, @machine_torecord); + +# Default Priority for Timers (Config: defaultprio) +my $default_prio = 50; + +# How many DVB-S cards are there (Config: DVBCards) +my $DVB_cards = 1; + +# How many seconds to substract from the time and to add to the duration +my $marginstart = 60*10; # Config: Marginstart +my $marginstop = 60*10; # Config: Marginstop + +# Shall Timers, on the same channel, be joined if they overlap +my $jointimers = 0; + +# Hostname/IP of DVB-Computer and the Port of VDR +my @Dest = ("localhost:2001"); # Config: Dest + +# Which VDR-Instance shall be used +my $currentVDR = 1; + +# Working-Variables +my ($title, $duration, $subtitle, $channel, $time, $description, $hit); +my (@time, @date); + +sub sub_die + { + my ($error) = @_; + &closesocket(); + die "$error"; + } + + +if ($ARGV[0]) + { + $currentVDR = $ARGV[0]; + } + +&init(); +&dumpdone() if ($debug & 8); +&dumptorecord() if ($debug & 1); +&fetchVDRTimers(); +&process_torecord(); +print "Timers before joining\n" if ($debug & 2 && $jointimers); +&dumptimers() if ($debug & 2); +if ($jointimers) + { + &jointimers(); + print "Timers after joining\n" if ($debug & 2); + &dumptimers() if ($debug & 2); + } + +&printtimers(); +&transfertimers(); +&closesocket(); + +# +# Subfunctions +# + +sub dumpdone() + { + print "Start Done-dump\n"; + print "Titledone: \"$title_done\"\n"; + print "Subtitledone \"$subtitle_done\"\n"; + print "End Done-dump\n"; + } + +sub dumptorecord() + { + print "Start Torecord-dump\n"; + print "Regex-Title: $title_torecord\n"; + print "Regex-Subtitle: $subtitle_torecord\n"; + print "Regex-Description: $description_torecord\n"; + foreach my $num (0 .. $num_torecord) + { + print "Timer Number $num: "; + + print "Title: \"$title_torecord[$num]\" " if ($title_torecord[$num]); + print "Title: \"\" " unless ($title_torecord[$num]); + + print "Subtitle: \"$subtitle_torecord[$num]\" "if ($subtitle_torecord[$num]); + print "Subtitle: \"\" " unless ($subtitle_torecord[$num]); + + print "Description: \"$description_torecord[$num]\" " if ($description_torecord[$num]); + print "Description: \"\" " unless ($description_torecord[$num]); + + print "Timeframe: \"$timeframe_torecord[$num]\" " if ($timeframe_torecord[$num]); + print "Timeframe: \"\" " unless ($timeframe_torecord[$num]); + + print "Channel: \"". join (";",@{$channel_torecord[$num]})."\" " if ($channel_torecord[$num]); + print "Channel: \"\" " unless ($channel_torecord[$num]); + + print "Prio: \"$prio_torecord[$num]\" " if ($prio_torecord[$num]); + print "Prio: \"\" " unless ($prio_torecord[$num]); + + print "Timertitle: \"$timer_title_torecord[$num]\" " if ($timer_title_torecord[$num]); + print "Timertitle: \"\" " unless ($timer_title_torecord[$num]); + + print "Marginstart: \"$marginstart_torecord[$num]\" " if ($marginstart_torecord[$num]); + print "Marginstart: \"\" " unless ($marginstart_torecord[$num]); + + print "Marginstop: \"$marginstop_torecord[$num]\" " if ($marginstop_torecord[$num]); + print "Marginstop: \"\" " unless ($marginstop_torecord[$num]); + + print "Machine: \"$machine_torecord[$num]\" " if ($machine_torecord[$num]); + print "Machine: \"\" " unless ($machine_torecord[$num]); + + print "\n"; + } + print "End Torecord-dump\n"; + } + +sub dumptimers() + { + print "Start Timers-dump\n"; + foreach $time (sort {$a <=> $b} keys %Timer) + { + foreach $channel (sort keys %{%Timer->{$time}}) + { + foreach $title (sort keys %{%Timer->{$time}->{$channel}}) + { + my ($prio, @time, @date, @time2); + my ($realtitle); + @time = &GetTime ($time); + @date = &GetDay ($time); + @time2 = &GetTime ($time + $Timer{$time}{$channel}{$title}{duration}); + $subtitle = $Timer{$time}{$channel}{$title}{subtitle}; + $prio = $Timer{$time}{$channel}{$title}{prio}; + $realtitle = $Timer{$time}{$channel}{$title}{real_title}; + print "2:$channels{$channel}{number}:$date[1]:$time[0]$time[1]:$time2[0]$time2[1]:$prio:99:$title:Title: \"$realtitle\"||Subtitle: \"$subtitle\":$Timer{$time}{$channel}{$title}{VDR}\n"; + } + } + } + print "End Timers-dump\n"; + } + +sub printtimers() + { + foreach $time (sort {$a <=> $b} keys %Timer) + { + foreach $channel (sort keys %{%Timer->{$time}}) + { + foreach $title (sort keys %{%Timer->{$time}->{$channel}}) + { + my ($prio, @time, @date, @time2); + if ($Timer{$time}{$channel}{$title}{VDR} eq 0) + { + my ($realtitle); + @time = &GetTime ($time); + @date = &GetDay ($time); + @time2 = &GetTime ($time + $Timer{$time}{$channel}{$title}{duration}); + $subtitle = $Timer{$time}{$channel}{$title}{subtitle}; + $prio = $Timer{$time}{$channel}{$title}{prio}; + $realtitle = $Timer{$time}{$channel}{$title}{real_title}; + + print "2:$channels{$channel}{number}:$date[1]:$time[0]$time[1]:$time2[0]$time2[1]:$prio:99:$title:Title: \"$realtitle\"||Subtitle: \"$subtitle\"\n"; + } + } + } + } + } + +sub transfertimers() + { + foreach $time (sort {$a <=> $b} keys %Timer) + { + foreach $channel (sort keys %{%Timer->{$time}}) + { + foreach $title (sort keys %{%Timer->{$time}->{$channel}}) + { + my ($prio, @time, @date, @time2, $realtitle, $result); + if ($Timer{$time}{$channel}{$title}{VDR} eq 0) + { + @time = &GetTime ($time); + @date = &GetDay ($time); + @time2 = &GetTime ($time + $Timer{$time}{$channel}{$title}{duration}); + $subtitle = $Timer{$time}{$channel}{$title}{subtitle}; + $prio = $Timer{$time}{$channel}{$title}{prio}; + $realtitle = $Timer{$time}{$channel}{$title}{real_title}; + + ($result) = GetSend ("newt 2:$channels{$channel}{number}:$date[1]:$time[0]$time[1]:$time2[0]$time2[1]:$prio:99:$title:Title: \"$realtitle\"||Subtitle: \"$subtitle\""); + print "Timer: $result" if ($debug & 2); + } + } + } + } + } + +# Convert the Unix-Time-Stamp into "month" and "Day of month" +sub GetDay + { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(shift); + $mon++; + $mon = sprintf ("%02i",$mon); + $mday = sprintf ("%02i",$mday); + return ($mon, $mday); + } + +# Convert the Unix-Time-Stramp into "hour" and "minute" +sub GetTime + { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(shift); + $hour = sprintf ("%02i",$hour); + $min = sprintf ("%02i",$min); + return ($hour, $min); + } + +# Workaround some EPG-Bugs +sub correct_epg_data + { + if ($subtitle) + { + # For Pro-7. Remove $title from $subtitle + $subtitle =~ s/$title\s\/\s//; + + # For VOX & VIVA. The Format it '"<Subtitle>". <Description>' + if ($subtitle =~ /^\"(.*?)\"\.\s(.*)/) + { + # Lets see if there are Channels that where the VOX/VIVA scheme matches, but also have a description + if ($description) + { + sub_die ("Subtitle: \"$subtitle\"\nDescription\"$description\"\n"); + } + $subtitle = $1; + $description = $2; + } + elsif ($channel eq "VIVA") + { + if ($subtitle =~ /^\s(.*)/) + { + $subtitle = ""; + $description = $1; + } + } + } + + # Workaround for the broken PRO-7/Kabel-1 EPG-Date. If Time is between 00.00 and 05.00 the time is shifted forward by a day + if ($channel eq "Pro-7" || $channel eq "Kabel-1") + { + my (@time); + @time = GetTime ($time); + if ($time[0] >= 0 && ($time[0] <= 4 || ($time[0] == 5 && $time[1] == 0))) + { + $time += 24*60*60; + } + } +} + +# Add a Recording into the "to record"-List +sub addtimer + { + my ($hit, $title, $realtitle, $subtitle, $channel, $time, $duration, $prio, $VDR, $time2, $title2, $channel2, $marginstart, $marginstop); + ($title, $realtitle, $subtitle, $channel, $time, $duration, $prio, $VDR, $marginstart, $marginstop) = @_; +# print "Title: \"$title\" Realtitle: \"$realtitle\" Subtitle: \"$subtitle\" Channel: \"$channel\" Time: \"$time\" Duration: \"$duration\" Prio: \"$prio\" VDR: \"$VDR\"\n"; + + $hit = 1; + + foreach $time2 (sort keys %Timer) + { + foreach $title2 (sort keys %{%Timer->{$time2}->{$channel}}) + { + my ($ctime, $ctime2); + $ctime = $time2; + $ctime2 = $time2 + $Timer{$time2}{$channel}{$title2}{duration}; + + if (($time >= $ctime) && ($time <= $ctime2)) + { + undef $hit; + } + } + } + + + if ($hit) + { + $time -= $marginstart; + $duration += $marginstart + $marginstop; + $Timer{$time}{$channel}{$title}{duration}=$duration; + $Timer{$time}{$channel}{$title}{subtitle}=$subtitle; + $Timer{$time}{$channel}{$title}{prio}=$prio; + $Timer{$time}{$channel}{$title}{VDR}=$VDR; + $Timer{$time}{$channel}{$title}{real_title}=$realtitle; + } + } + +sub deltimer() + { + my ($time, $channel, $title, $delete_from_VDR); + ($time, $channel, $title, $delete_from_VDR) = @_; + +# if ($delete_from_VDR) +# { +# if ($Timer{$time}{$channel}{$title}{VDR}) +# { +# if ($Timer{$time}{$channel}{$title}{VDR} =~ s/ ^R/) +# { +# print "Error: A Repeating-Timer can't be deleted from VDR: \"$title\"\n"; +# } +# elsif ($Timer{$time}{$channel}{$title}{VDR} < 1000000) +# { +# print "A User-Programmed Timer has been deleted from VDR: \"$title\"\n"; +# } +# else +# { +# +# } +# } +# } + + delete $Timer{$time}{$channel}{$title}{duration}; + delete $Timer{$time}{$channel}{$title}{subtitle}; + delete $Timer{$time}{$channel}{$title}{prio}; + delete $Timer{$time}{$channel}{$title}{VDR}; + delete $Timer{$time}{$channel}{$title}{real_title}; + delete $Timer{$time}{$channel}{$title}; + delete $Timer{$time}{$channel} if (keys %{ $Timer{$time}{$channel} } == 1); + delete $Timer{$time} if (keys %{ $Timer{$time} } == 1); + } + +sub jointimers + { + # + # FIXME: 2 Timers on the same channel will always be joined. + # It should be checked if there is another DVB-Card available. + # + # FIXME2: When one timer is already programmed in VDR, delete that timer in VDR. + my ($running, $counter, @times, $channel, $title, $channel2, $title2); + $running = 1; + outer: while ($running) + { + $counter = 0; + @times = sort {$a <=> $b} keys %Timer; + + # We only need to check till the second last timer. The last one can't have a overlapping one. + while ($counter < $#times) + { + foreach $channel (sort keys %{%Timer->{$times[$counter]}}) + { + foreach $title (sort keys %{%Timer->{$times[$counter]}->{$channel}}) + { + if ($times[$counter + 1] < ($times[$counter] + $Timer{$times[$counter]}{$channel}{$title}{duration})) + { + foreach $channel2 (sort keys %{%Timer->{$times[$counter + 1]}}) + { + foreach $title2 (sort keys %{%Timer->{$times[$counter + 1]}->{$channel}}) + { + if ($channel eq $channel2) + { + my ($duration, $subtitle, $prio, $realtitle, $duration2, $subtitle2, $prio2, $realtitle2); + # Values from Lower-Timer + $duration = $Timer{$times[$counter]}{$channel}{$title}{duration}; + $subtitle = $Timer{$times[$counter]}{$channel}{$title}{subtitle}; + $prio = $Timer{$times[$counter]}{$channel}{$title}{prio}; + $realtitle = $Timer{$times[$counter]}{$channel}{$title}{real_title}; + + # Values from Higher-Timer + $duration2 = $Timer{$times[$counter + 1]}{$channel2}{$title2}{duration}; + $subtitle2 = $Timer{$times[$counter + 1]}{$channel2}{$title2}{subtitle}; + $prio2 = $Timer{$times[$counter + 1]}{$channel2}{$title2}{prio}; + $realtitle2 = $Timer{$times[$counter + 1]}{$channel2}{$title2}{real_title}; + + # Use the Higher Priority for the new Timer + $prio = ($prio > $prio2) ? $prio : $prio2; + + # Delete the two "Obsolet" Timers + &deltimer ($times[$counter], $channel, $title); + &deltimer ($times[$counter + 1], $channel2, $title2); + + # And set the new one + &addtimer ("$title + $title2", "$realtitle\~$realtitle2", "$subtitle\~$subtitle2", $channel, $times[$counter], $duration2 + ($times[$counter + 1 ] - $times[$counter]),$prio,0,0,0); + + # Now a Value is "missing", so we will redo the whole thing. (This will do three-times JOIN correct) + redo outer; + } + } + } + } + } + } + $counter++; + } + undef $running; + } + } + +sub process_torecord + { + my ($first_hit, $prio, $timer_title); + foreach $title (sort keys %Program) + { + foreach $channel (sort keys %{%Program->{$title}}) + { + foreach $time (sort {$a <=> $b} keys %{%Program->{$title}->{$channel}}) + { + undef $hit; + + # First look if any of the Title/Subtitle/Description REs match + if ($title =~ /$title_torecord/i) + { + $hit = 1; + } + elsif ($Program{$title}{$channel}{$time}{subtitle} && $Program{$title}{$channel}{$time}{subtitle} =~ /$subtitle_torecord/i) + { + $hit = 1; + } + elsif ($Program{$title}{$channel}{$time}{description} && $Program{$title}{$channel}{$time}{description} =~ /$description_torecord/i) + { + $hit = 1; + } + + # Now look if we have a "exact" hit + if ($hit) + { + my ($counter); + undef $hit; + foreach $counter (0 .. $num_torecord) + { + + if ($title_torecord[$counter]) + { + if (!($title =~ /$title_torecord[$counter]/i)) + { + next; + } + } + + if ($subtitle_torecord[$counter]) + { + if (!($Program{$title}{$channel}{$time}{subtitle} =~ /$subtitle_torecord[$counter]/i)) + { + next; + } + elsif (!$title_torecord[$counter] && !$description_torecord[$counter]) + { + next; + } + } + + if ($description_torecord[$counter]) + { + if ($Program{$title}{$channel}{$time}{description}) + { + if (!($Program{$title}{$channel}{$time}{description} =~ /$description_torecord[$counter]/i)) + { + next; + } + } + elsif (!$title_torecord[$counter] && !$subtitle_torecord[$counter]) + { + next; + } + } + + if ($channel_torecord[$counter]) + { + my ($hit); + # Blacklist-Mode + if ($channel_torecord[$counter][0] =~ /^!/) + { + $hit = 1; + foreach (0 .. $#{$channel_torecord[$counter]}) + { + # Strip a possibel "!" Charactar + $channel_torecord[$counter][$_] =~ /^!?(.*)/; + if ($channel =~ /^$1$/) + { + undef $hit; + last; + } + } + } + # Whitelist-Mode + else + { + undef $hit; + foreach (0 .. $#{$channel_torecord[$counter]}) + { + # Strip a possibel "!" Charactar + $channel_torecord[$counter][$_] =~ /^!?(.*)/; + if ($channel =~ /^$1$/) + { + $hit = 1; + last ; + } + } + } + if (!$hit) + { + next; + } + } + + if ($timeframe_torecord[$counter]) + { + my (@time, $time2, $ctime, $ctime2); + @time = GetTime($time); + $time2 = "$time[0]$time[1]"; + + ($ctime, $ctime2) = split (/\-/,$timeframe_torecord[$counter]); + + if (!$ctime) + { + $ctime = "0"; + } + if (!$ctime2) + { + $ctime2 = "2400"; + } + + if ($ctime < $ctime2) + { + if (!($time2 >= $ctime && $time2 <= $ctime2)) + { + next; + } + } + else + { + if (!(($time2 >= $ctime && $time2 <= "2400") || ($time2 >= "0" && $time2 <= $ctime2))) + { + next; + } + } + } + + if ($prio_torecord[$counter]) + { + $prio = $prio_torecord[$counter]; + } + else + { + $prio = 50; + } + + # What Title to use for the timer + if ($timer_title_torecord[$counter]) + { + $timer_title = $timer_title_torecord[$counter] + } + elsif ($title_torecord[$counter]) + { + $timer_title = $title_torecord[$counter] + } + else + { + $timer_title = $title; + } + + my ($subtitle); + if ($Program{$title}{$channel}{$time}{subtitle}) + { + $subtitle = $Program{$title}{$channel}{$time}{subtitle}; + } + else + { + $subtitle = ""; + } + + &addtimer ($timer_title,$title,$subtitle,$channel,$time,$Program{$title}{$channel}{$time}{duration},$prio,0,$marginstart_torecord[$counter],$marginstop_torecord[$counter]); + last; + } + } + } + } + } + } + +# Open the connection to VDR +sub initsocket + { + my ($Dest, $Port) = split (/\:/,$Dest[$currentVDR - 1],2); + my $iaddr = inet_aton($Dest); + my $paddr = sockaddr_in($Port, $iaddr); + + socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp')); + connect(SOCKET, $paddr) or sub_die ("Can't connect to VDR\n"); + select(SOCKET); $| = 1; + select(STDOUT); + + while (<SOCKET>) { + last if substr($_, 3, 1) ne "-"; + } + } + +# Send a command to VDR and read back the result +sub GetSend + { + my ($command, @retval); + + while ($command = shift) + { + print SOCKET "$command\r\n"; + while (<SOCKET>) { + (@retval) = (@retval, $_); + last if substr($_, 3, 1) ne "-"; + } + } + + foreach my $retval (@retval) + { + $retval =~ s/\x0d//g; + } + return (@retval); + } + +# Close the socket to VDR +sub closesocket + { + print SOCKET "Quit\r\n"; + close(SOCKET); + } + + +# Fetch the timers-List from VDR via SVDR and process it. +sub fetchVDRTimers + { + my (@timers, $timer, $position, $active, $channel, $day, $start, $end, $prio, $ttl, $title, $subtitle, $minute, $duration); + my ($utime, $utime2); + + # First fetch the timers-list from VDR + @timers = GetSend ("lstt"); + + foreach $timer (@timers) + { +# $timer =~ s/\x0d//g; + chomp $timer; + # a Valid Timer-line beginns with "250" + if ($timer =~ s/250-|250\s//) + { + # Extract the Position in front of the line + ($position, $timer) = split (/\s/,$timer,2); + +# print "Position: \"$position\" Timer: \"$timer\"\n"; + # Split the : seperated values + ($active, $channel, $day, $start, $end, $prio, $ttl, $title, $subtitle) = split (/\:/,$timer,9); + + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + + # If the string is exactly 7 char wide, then its a "repeating"-timer + if ($active >= 1) + { + if ($day =~ /(.)(.)(.)(.)(.)(.)(.)/) + { + my (@days); + @days = ($1, $2, $3, $4, $5, $6, $7); + ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); + + $start =~ /(\d\d)(\d\d)/; + $hour = $1; + $minute = $2; + $utime = timelocal 0, $minute, $hour, $mday, $mon, $year; + $end =~ /(\d\d)(\d\d)/; + $hour = $1; + $minute = $2; + $utime2 = timelocal 0, $minute, $hour, $mday, $mon, $year; + if ($end < $start) + { + $utime2 += 24*60*60; + } + $duration = $utime2 - $utime; + + # "Normalize" the timestamp to monday + $utime = $utime - ($wday * 24 * 60 *60); + + foreach my $num (0 .. $#days) + { + if ($days[$num] ne "-") + { + my $utime3; + # Todays before today will be shifted in the next week + if (($num + 1) < $wday) + { + $utime3 = $utime + (($num + 7 + 1) * 24 * 60 * 60); + } + else + { + $utime3 = $utime + (($num + 1) * 24 * 60 * 60); + } + &addtimer ($title,$title,$subtitle,$channels[$channel],$utime3,$duration,$prio,"R$position",0,0); + } + } + } + + # When the Day-Value is between 1 and 31, then its a "One time" Timer + elsif (($day >= 1) && ($day <= 31)) + { + if ($active == "2") + { + $position += 1000000; + } + # When the Day is before the Current-Day, then the Timer is for the next month + if ($day < $mday) + { + $mon++; + if ($mon == 12) + { + $mon = 0; + $year ++; + } + } + $start =~ /(\d\d)(\d\d)/; + $hour = $1; + $minute = $2; + $utime = timelocal 0, $minute, $hour, $day, $mon, $year; + $end =~ /(\d\d)(\d\d)/; + $hour = $1; + $minute = $2; + $utime2 = timelocal 0, $minute, $hour, $day, $mon, $year; + if ($end < $start) + { + $utime2 += 24*60*60; + } + $duration = $utime2 - $utime; + + &addtimer ($title,$title,$subtitle,$channels[$channel],$utime,$duration,$prio,$position,0,0); + } + } + } + } + } + +# Parse file "epg.data" +sub initepgdata + { + open (FI,"epg.data") or sub_die ("Can't open file \"epg.data\"\n"); + + while (<FI>) + { + # Begin Channel + if (/^C\s(\d+)\s+(.+)/) + { + $channel = $2; + while (<FI>) + { + # End Channel + if (/^c$/) + { + last; + } + # Begin Timer + elsif (/^E\s(\d+)\s+(\d+)\s+(\d+)$/) + { + # Undef this Variables because it is possibel that not every timer uses this values + undef $duration; + undef $subtitle; + undef $description; + + $time=$2; + $duration=$3; + } + # Title + elsif (/^T\s(.*)/) + { + $title = $1; + } + # Subtitle + elsif (/^S\s(.*)/) + { + $subtitle=$1; + } + # Description + elsif (/^D\s(.*)/) + { + $description=$1; + } + # End Timer + elsif (/^e$/) + { + # Only accept timers that are in the future + if ($time < time) + { + next; + } + + # Work around the diffrent Bugs in the data + &correct_epg_data(); + + # Check if the title is in the DEEP-Blacklist + if ($title =~ /$title_deepblack/i) + { + next; + } + + # Check if the Title & Subtitle is in the Done-List + if ($title =~ /$title_done/) + { + if ($subtitle) + { + if ($subtitle =~ /$subtitle_done/) + { + next; + } + } + } + + $Program{$title}{$channel}{$time}{duration}=$duration; + if ($subtitle) + { + $Program{$title}{$channel}{$time}{subtitle}=$subtitle; + } + if ($description) + { + $Program{$title}{$channel}{$time}{description}=$description; + } + } + } + } + } + close (FI); + } + +# What is a Movie (When correctly stored into Subtitle) +sub initmovie + { + my (@list,$list); + open (FI,"$ENV{HOME}/.master-timer/subtitle-movie") or return; + @list = <FI>; + close(FI); + + foreach $list (@list) + { + chomp $list; + } + $subtitle_movie = join ('|',@list); + } + +# What should be blacklistet +sub initblacklist + { + my (@list,$list); + if (open (FI,"$ENV{HOME}/.master-timer/deepblack")) + { + @list = <FI>; + close(FI); + + foreach $list (@list) + { + chomp $list; + } + $title_deepblack = join ('|',@list); + } + else + { + $title_deepblack = "^\$"; + } + } + +# What is already recorded/Should not be recorded +sub initdone + { + my (@list,$list, %title_done, %subtitle_done, $title_temp, $subtitle_temp); + if (open (FI,"$ENV{HOME}/.master-timer/done")) + { + @list = <FI>; + close (FI); + + foreach $list (@list) + { + chomp $list; + ($title_temp,$subtitle_temp) = split (/\|/,$list); + if ($title_temp) + { + $title_done{"^$title_temp\$"} = 1; + } + if ($subtitle_temp) + { + $subtitle_done{"^$subtitle_temp\$"} = 1; + } + } + $title_done = join ('|',sort keys %title_done); + $subtitle_done = join ('|',sort keys %subtitle_done); + + # Ein paar Zeichen Escapen + $title_done =~ s/\?/\\\?/g; + $title_done =~ s/\+/\\\+/g; + $subtitle_done =~ s/\?/\\\?/g; + $subtitle_done =~ s/\+/\\\+/g; + + # Now delete Timers in VDR that are already in the done-List + my ($position, $timer, $active, $g, $title, $subtitle, $counter, @todel); + $counter = 0; + @list = GetSend ("LSTT"); + + foreach $timer (@list) + { +# $timer =~ s/0x0d//g; + chomp $timer; + if ($timer =~ s/250-|250\s//) + { + ($position, $timer) = split (/\s/,$timer,2); + # Split the : seperated values + ($active, $g, $g, $g, $g, $g, $g, $title, $subtitle) = split (/\:/,$timer,9); + if ($active == 2) + { + # Title: "Shakespeare in Love"||Subtitle: "Romanze" + my ($ctitle, $csubtitle); + if ($subtitle && $subtitle =~ /^Title\:\s\"(.*)\"\|\|Subtitle\:\s\"(.*)\"/) + { + $title = $1; + $subtitle = $2; + if ($subtitle) + { + my (@titles, @subtitles, $num, $hit); + undef $hit; + @titles = split (/\~/,$title); + @subtitles = split (/\~/,$subtitle); + foreach $num (0 .. $#titles) + { + if ($titles[$num] =~ /$title_done/ && $subtitles[$num] =~ /$subtitle_done/) + { + $hit = 1; + } + else + { + undef $hit; + last; + } + } + + if ($hit) + { + my ($result); + print "Delete Timer: $title $subtitle\n" if ($debug & 4); + $position -= $counter; + ($result) = GetSend ("DELT $position"); + print "Result: $result" if ($debug & 4); + if ($result =~ /^250/) + { + $counter++; + } + } + } + } + } + } + } + } + } + +# What should be recorded +sub inittorecord + { + my (@list, $list, $title, $subtitle, $description, $channel, $timeframe, $prio, $timer_title, $margin, $machine, @title_list, @subtitle_list, @description_list); + my $counter = 0; + open (FI,"$ENV{HOME}/.master-timer/torecord") or sub_die ("Can't open file \"torecord\"\n"); + @list = <FI>; + close(FI); + + foreach $list (0 .. $#list) + { + chomp $list[$list]; + if ($list[$list] && !($list[$list] =~ /^\#/)) + { + ($title, $subtitle, $description, $channel, $timeframe, $prio, $timer_title, $margin, $machine) = split (/\|/,$list[$list]); + + # Accept torecord only if it is for the current machine + if ((!$machine && $currentVDR == 1) || $machine == $currentVDR) + { + if ($title) + { + $title_torecord[$counter] = $title; + $title_list[$#title_list + 1] = $title; + } + if ($subtitle) + { + $subtitle_torecord[$counter] = $subtitle; + $subtitle_list[$#subtitle_list + 1] = $subtitle; + } + if ($description) + { + $description_torecord[$counter] = $description; + $description_list[$#description_list + 1] = $description; + } + if ($channel) + { + my (@temp); + @temp = split (/\;/,$channel); + foreach (0 .. $#temp) + { + $channel_torecord[$counter][$_] = $temp[$_]; + } + } + if ($timeframe) + { + $timeframe_torecord[$counter] = $timeframe; + } + if ($prio) + { + $prio_torecord[$counter] = $prio; + } + else + { + $prio_torecord[$counter] = $default_prio; + } + if ($timer_title) + { + $timer_title_torecord[$counter] = $timer_title; + } + if ($margin) + { + my ($start, $stop); + ($start, $stop) = split (/;/,$margin, 2); + $marginstart_torecord[$counter] = $start if ($start); + $marginstop_torecord[$counter] = $stop if ($stop); + } + # Set Default-Margins if not margins defined + $marginstart_torecord[$counter] = $marginstart if (!$marginstart_torecord[$counter]); + $marginstop_torecord[$counter] = $marginstop if (!$marginstop_torecord[$counter]); + $counter++; + } + } + } + + $num_torecord = $counter - 1; + + $title_torecord = join ('|',@title_list); + $subtitle_torecord = join ('|',@subtitle_list); + $description_torecord = join ('|',@description_list); + + if (!$title_torecord) + { + $title_torecord = "^Dieseshierwirdgarantiertnieundnimmeraufirgendetwassinnvollesmatchen\$"; + } + if (!$subtitle_torecord) + { + $subtitle_torecord = "^Dieseshierwirdgarantiertnieundnimmeraufirgendetwassinnvollesmatchen\$"; + } + if (!$description_torecord) + { + $description_torecord = "^Dieseshierwirdgarantiertnieundnimmeraufirgendetwassinnvollesmatchen\$"; + } + } + +# Parse the "channels.conf" of VDR +sub initchannellist + { + my ($counter, $chan, $garbage, $card, @temp_channels, $temp, $i); + + @temp_channels = GetSend ("LSTC"); + + foreach $i (0 .. $#temp_channels) + { + $temp = $temp_channels[$i]; +# $temp =~ s/\x0d//g; + chomp $temp; + + if ($temp =~ s/250-|250\s//) + { + ($counter, $temp) = split (/\s/,$temp,2); + ($chan, $garbage,$garbage, $garbage, $garbage, $garbage, $garbage, $card, $garbage) = split (/\:/,$temp); + $channels[$counter] = $chan; + $channels{$chan}{number} = $counter; + $channels{$chan}{card} = $card; + $counter++; + } + } + } + +sub initconfigfile + { + open (FI,"$ENV{HOME}/.master-timer/config") or return; + while (<FI>) + { + s/\#.*//; + chomp; + if ($_) + { + my ($key, $value); + ($key, $value) = split (/\s+=\s+/); + if ($key =~ /^debug$/i) + { + $debug = $value; + print "Debug-Level = $value\n" if ($debug & 16); + } + elsif ($key =~ /^marginstart$/i) + { + print "Marginstart = $value\n" if ($debug & 16); + $marginstart = $value; + } + elsif ($key =~ /^marginstop$/i) + { + print "Marginstop = $value\n" if ($debug & 16); + $marginstop = $value; + } + elsif ($key =~ /^DVBCards$/i) + { + print "DVB_Cards = $value\n" if ($debug & 16); + $DVB_cards = $value; + } + elsif ($key =~ /^defaultprio$/i) + { + print "Default Priority = $value\n" if ($debug & 16); + $default_prio = $value; + } + elsif ($key =~ /^Dest$/i) + { + print "Destination Host/IP:Port = $value\n" if ($debug & 16); + @Dest = split (/\s+/,$value); + } + elsif ($key =~ /^jointimers$/i) + { + print "Join Timers = $value\n" if ($debug & 16); + $jointimers = $value; + } + else + { + print "Unkown Key: \"$key\" with Value: \"$value\"\n"; + } + } + } + print "End Config\n" if ($debug & 16); + } + +sub init + { + &initconfigfile(); + &initsocket(); + &initmovie(); + &initblacklist(); + &initdone(); + &initchannellist(); + &initepgdata(); + &inittorecord(); + } diff --git a/Tools/master-timer/process_summary.pl b/Tools/master-timer/process_summary.pl new file mode 100755 index 0000000..ebe6300 --- /dev/null +++ b/Tools/master-timer/process_summary.pl @@ -0,0 +1,79 @@ +#!/usr/bin/perl -w + +$dir = "/home/ms/.master-timer"; + +open (FI,"$dir/done") or die "Can't open \"done\"\n"; +while (<FI>) + { + chomp; + if ($_) + { + ($title,$subtitle) = split (/\|/,$_,2); + $Done{$title}{$subtitle}=1; + } + } +close (FI); + +&traverse('/video'); + +if ($hit) + { + rename ("$dir/done","$dir/done.bak"); + open (FO,">$dir/done"); + foreach $title (sort keys %Done) + { + foreach $subtitle (sort keys %{%Done->{$title}}) + { + print FO "$title\|$subtitle\n"; + } + } + } + +sub traverse + { + local($dir) = shift; + local($path); + unless (opendir(DIR, $dir)) + { + warn "Can't open $dir\n"; + closedir(DIR); + return; + } + foreach (readdir(DIR)) + { + next if $_ eq '.' || $_ eq '..'; + $path = "$dir/$_"; + if (-d $path) # a directory + { + &traverse($path); + } + if ($_ eq "summary.vdr") + { + open (FI,"$path") or die "Can't open \"$path\"\n"; + @lines = <FI>; + close (FI); + if ($lines[0] =~ /^Title\:\s\"(.*)\"/) + { + @titles = split (/\~/,$1); + if ($lines[2] && $lines[2] =~ /^Subtitle\:\s\"(.*)\"/) + { + @subtitles = split (/\~/,$1); + foreach $num (0 .. $#titles) + { + if ($titles[$num] && $subtitles[$num]) + { + if (!$Done{$titles[$num]}{$subtitles[$num]}) + { + $Done{$titles[$num]}{$subtitles[$num]}=1; + $hit = 1; + } + } + } + } + } + } + } + closedir(DIR); + } + + diff --git a/Tools/master-timer/sample/channels-to-scan b/Tools/master-timer/sample/channels-to-scan new file mode 100644 index 0000000..6acf157 --- /dev/null +++ b/Tools/master-timer/sample/channels-to-scan @@ -0,0 +1,8 @@ +1 +2 +3 +4 +5 +13 +18 +21 diff --git a/Tools/master-timer/sample/config b/Tools/master-timer/sample/config new file mode 100644 index 0000000..d01c8a8 --- /dev/null +++ b/Tools/master-timer/sample/config @@ -0,0 +1,14 @@ +# How Many Seconds "too early" should the timer begin +marginstart = 600 +# How Many Seocnds "too long" should the timer end +marginstop = 600 +# When the Prio isn't provied in the config-File use this value +defaultprio = 50 +# How many DVB-Cards are installed in the Computer (Not used yet) +DVBCards = 3 +# IP/Hostname:Port of the Destinations (Space is used for delimiter) +Dest-Host = localhost:2001 +# Should Timers on the same channels be joined when they overlapp (0 = off) +jointimers = 1 +# Debug-Level +debug = 0 diff --git a/Tools/master-timer/sample/deepblack b/Tools/master-timer/sample/deepblack new file mode 100644 index 0000000..63b4f9e --- /dev/null +++ b/Tools/master-timer/sample/deepblack @@ -0,0 +1,79 @@ +Für alle Fälle Stefanie +'MAX' - Das ganze Leben! +10 vor 11 +17:30 live +18:30 +24 Stunden +Andreas Türck +Arabella +^BIZZ$ +Big Brother +Britt - Der Talk um Eins +Bärbel Schäfer +Call TV +Chicago Hope - Endstation Hoffnung +Chicago Hope +DIE REDAKTION +Dauerwerbesendungen +Die Harald Schmidt Show +Die Oliver Geissen Show +Die Quiz Show +Doppelter Einsatz +Dr. Stefan Frank - Der Arzt, dem die Frauen vertrauen +EXCLUSIV +EXTRA +Ehekriege +Ein Bayer auf Rügen +Emergency Room +Explosiv - Das Magazin +GIRLSCAMP +Glücksrad +Gute Zeiten, schlechte Zeiten +Hallo, Onkel Doc! +Hans Meiser +Hercules +Hinter Gittern - Der Frauenknast +Infomercials +Jeder gegen Jeden +K1 DIE REPORTAGE +K1 Das Magazin +K1 Nachrichten +Kickers +Kochduell +Nachrichten +Nicole - Entscheidung am Nachmittag +OP ruft Dr. Bruckner +PREMIERE WORLD - Das Programm +PROSIEBEN REPORTAGE +Peter Imhof +Programm ab +Programm von +Punkt 12 +Punkt 6 +Punkt 9 +RTL II News +RTL SHOP +RTL aktuell +RTL-Nachtjournal +SAT.1-FRÜHSTÜCKSFERNSEHEN +Spiegel TV-Reportage +UEFA Champions +fussball +fßball +Vera am Mittag +Wolffs Revier +Zapping +alphateam +peep! +s.a.m. +taff. +^blitz$ +SK Kölsch +^Becker$ +Kommissar Rex +Fit For Fun TV +Nur die Liebe zählt +Unsere kleine Farm +Die Waltons +^Die Zwei$ +^Sieben$ diff --git a/Tools/master-timer/sample/done b/Tools/master-timer/sample/done new file mode 100644 index 0000000..76819c7 --- /dev/null +++ b/Tools/master-timer/sample/done @@ -0,0 +1 @@ +Alles Routine|Komödie diff --git a/Tools/master-timer/sample/subtitle-movie b/Tools/master-timer/sample/subtitle-movie new file mode 100644 index 0000000..3b5a0ab --- /dev/null +++ b/Tools/master-timer/sample/subtitle-movie @@ -0,0 +1,41 @@ +^Abenteuerfilm$ +^Actionfilm$ +^Actionkomödie$ +^Actionthriller$ +^Agentenfilm$ +^Biografie$ +^Biographie$ +^Computeranimation$ +^Drama$ +^Episodenfilm$ +^Erotikfilm$ +^Familiendrama$ +^Fantasy$ +^Fantasykomödie$ +^Gangsterfilm$ +^Gerichtsfilm$ +^Gesellschaftsdrama$ +^Horrorfilm$ +^Horrorkomödie$ +^Kinderfilm$ +^Komödie$ +^Kriegsfilm$ +^Krimikomödie$ +^Kriminalfilm$ +^Liebesfilm$ +^Melodram$ +^Melodrama$ +^Musical$ +^Politthriller$ +^Psychothriller$ +^Road Movie$ +^Romanze$ +^Satire$ +^Science-Fiction$ +^Spielfilm$ +^TV Movie$ +^TV-Drama$ +^Thriller$ +^Western$ +^Zeichentrick$ +^Zeichentrickkomödie$ diff --git a/Tools/master-timer/sample/torecord b/Tools/master-timer/sample/torecord new file mode 100644 index 0000000..0306830 --- /dev/null +++ b/Tools/master-timer/sample/torecord @@ -0,0 +1,32 @@ +# Format: (Every field is "optional". +# [Title RE|Subtitle RE|Description RE|Channel-Name|Timeframe|Prio|Timer-Title|Marginstart;Marginstop|VDR-Instance] +# +# To record something at least one of the "Title", "Subtitle" or "Description" +# Fields has to be provided. This 3 fields are "include" and the rest are +# "exclude" fields! +# +# More than one channel definition can be provided. The delimiter is ";" +# Additionaly you can make a "blacklist" of Channels when you prepent a "!" to the first Channel Definition +# The "!" is only tested for the FIRST Channel definition. +# You can only have a white or a blacklist (Mixing doesn't make sense!) +# +# ex. Record the series "Deep Space Nine" on Sci-Fantasy in the timeframe 09:00 - 14:00 with 60 Seconds Marginstart and -60 Seconds Marginstop +# Deep Space Nine|||Sci-Fantasy|0900-1400|99|DS9|60;-60 +# +# Record all "Actionfilm"s with "Schwarzenegger" +# |Actionfilm|Schwarzenegger +# +Babylon 5|||!Pro-7||99|60;-60|1 +Deep Space Nine|||||99|DS9|60;-60|2 +Seven Days|||||99| +Stargate|||||99| +Futurama||||2100-2300|50| +Ally McBeal|||||99| +Snoops|||||50| +^Friends$|||||99|Friends| +Pensacola|||||50| +seaQuest|||||50| +||Paltrow|Sci Fantasy;13th Street;Star Kino;Cine Action;Cine Comedy;Romantic Movies;Studio Universal;Premiere||99| +||Aniston|||99| +Matrix + diff --git a/Tools/master-timer/scan-channels b/Tools/master-timer/scan-channels new file mode 100755 index 0000000..324181b --- /dev/null +++ b/Tools/master-timer/scan-channels @@ -0,0 +1,8 @@ +#!/bin/sh +old=`svdrpsend.pl chan | grep 250 | cut -d " " -f2` +for dat in `cat $HOME/.master-timer/channels-to-scan` +do + svdrpsend.pl "chan $dat" + sleep 30s +done +svdrpsend.pl "chan $old" -- cgit v1.2.3