Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[vdr] Re: Resort channels.conf
Hi Rainer,
here's my version of your script which should solve
these problems:
> There are 2 problems still to solve:
>
> -Informations about channels which are not in the "new"
> channels.conf will be lost (without a warning!)
>
> -Grouping infos will be lost (without a warning!).
>
> -Better rename solution.
And I tried to apply my "business" coding rules and added
many more comments and some other perlish things but I
hope you will like it anyway.
> (Please: Don't take it as a "reference implementation" ;-)
> It's only a -very- quick hack with a lot of work to done.
> If here is a perl hacker: pls. don't hesitate to sent a better
> version!)
The eye of the beholder :-)
Ok, here's my new version 0.03:
#!/usr/bin/perl
# Version 0.03
# Aranges a new VDR channel.conf file to the channel order
# given by a reference channel.conf file
#
# new channels will be added at the end of the new channel.conf
#
# channels with signal IDs not existing in new channel.conf
# are kept on their old place.
#
# renamed channels will keep their old name if lookup
# via sid is possible
#
# History:
# 140808 mf keep deleted channels
# keep grouping lines
# more perlish style
# 030808 rz accept norma channels.conf as input
# try to detect renames
# 020605 cp initial version
#
####################################################################
use strict;
use warnings;
####################################################################
# Constant Definitions
####################################################################
use constant DEBUG => 0; # not used yet
####################################################################
# Parameter Checks
####################################################################
if ( @ARGV < 3 ) {
Usage();
exit;
}
my $sourceFilename = $ARGV[0];
my $orderFilename = $ARGV[1];
my $targetFilename = $ARGV[2];
die "Source File '$sourceFilename' not found\n" if ( ! -f $sourceFilename );
die "Ordering File '$orderFilename' not found\n" if ( ! -f $orderFilename );
####################################################################
# Load Ordering File
####################################################################
# Open Ordering File and load complete
# contents into sortedChannels Array:
my @sortedChannels = ();
# Process complete File
open( ORDERFILE, "< $orderFilename" ) || die "Cannot open Ordering File
'$orderFilename': $!\n";
while ( my $line = <ORDERFILE> ) {
# Extract this line and put Channel Data into the
# Sorted Channel Array:
my $channel = ExtractChannelData( $line );
push( @sortedChannels, $channel );
} # while
close( ORDERFILE );
####################################################################
# Load new Source File
####################################################################
# Open the new channels.conf Source File and
# load Channels in two Lookup Hashes
my %newChannelName = (); # Hash: Key=Name, Value=New Channel Data
my %newChannelSID = (); # Hash: Key=SID, Value=New Channel Data
my @unsortedChannels = (); # Array: all new Channels
open( SOURCEFILE, "< $sourceFilename" ) || die "Cannot open Source File
'$sourceFilename': $!\n";
while ( my $lineBuffer = <SOURCEFILE> ) {
# Extract Channel data
my $channel = ExtractChannelData( $lineBuffer );
# Mark Channel unused first
$channel->{'Used'} = 0;
# No need to remember any Grouping or Command Lines
# because this file will never be sorted.
if ( IsChannelData( $channel ) ) {
# Remember this new Channel for later use
push( @unsortedChannels, $channel );
# We put this new Channel in two Lookup Hashes:
# One for Name-Lookup and one for SID-Lookup
$newChannelName{ $channel->{'Name'} } = $channel;
$newChannelSID{ $channel->{'SID'} } = $channel;
}
} # while
close( SOURCEFILE );
####################################################################
# Write ordered channels in given order
####################################################################
# We create the new target file and
open( TARGETFILE, "> $targetFilename" ) || die "Cannot open Target File
'$targetFilename': $!\n";
# Walk through all sorted Channels and try to find the new
# Channel Data for this line:
my $renamedChannels = 0;
my $removedChannels = 0;
foreach my $oldChannel ( @sortedChannels ) {
# Try to find the matching new Channel now:
my $newChannel;
# Is this Channel Object just a Group Line
# or a real Channel.
if ( IsChannelData( $oldChannel ) ) {
# We try to find the new Channel Data by Name first:
if ( exists $newChannelName{ $oldChannel->{'Name'} } ) {
# Ok, this is our new Channel Data
$newChannel = $newChannelName{ $oldChannel->{'Name'} };
}
elsif ( exists $newChannelSID{ $oldChannel->{'SID'} } ) {
# Ok, this is our new Channel Data
$newChannel = $newChannelSID{ $oldChannel->{'SID'} };
# But we want to keep the old name:
$newChannel->{'Name'} = $oldChannel->{'Name'};
# This is a renamed Channel:
$renamedChannels++;
}
else {
# New channel.conf has no matching channel. Not
# found by name nor by sid...
# ...well, we just keep the old Channel Data :-)
$newChannel = $oldChannel;
# This is a removed Channel
$removedChannels++;
}
}
else {
# Just a Group Line, we just keep it
$newChannel = $oldChannel;
}
# Write the new channel.conf line of this channel
print TARGETFILE ComputeChannelLine( $newChannel );
# Mark this new Channel as used, so we can
# examine the new unused channels later...
$newChannel->{'Used'} = 1;
}
# Now write all new unused channels in
# original order. This is the only use
# of our unsortedChannels Array ;-)
print TARGETFILE ":NEW CHANNELS\n";
my $addedChannels = 0;
foreach my $newChannel ( @unsortedChannels ) {
# Only print channels not already used
if( $newChannel->{'Used'} == 0 ) {
# Write the new channel.conf line of this channel
print TARGETFILE ComputeChannelLine( $newChannel );
# Mark Channel as used
$newChannel->{'Used'} = 1;
# One new Channel added
$addedChannels++;
}
}
close( TARGETFILE );
printf STDERR "Updated %s existing channels.\n", scalar( @sortedChannels );
printf STDERR "Added %s new channels.\n", $addedChannels;
printf STDERR "Found %s renamed channels.\n", $renamedChannels;
printf STDERR "Found %s removed channels.\n", $removedChannels;
# Finish
exit 0;
##########################################################################
# Subroutines follow here...
##########################################################################
# ExtractChannelData
#
# Takes a line from an channel.conf and creates a Channel Data
# Hash with all it's data. The Hash reference will be returned.
#
# Parameter
# [0] single line of channel.conf
#
# Returns
# Reference to Channel Data Hash
#
sub ExtractChannelData {
# Parameters
my $lineBuffer = $_[0];
# Rückgabe
my $channelData = { };
# Remove CR/LF
chomp( $lineBuffer );
# Split this line
my ( $Name, $Frequency, $Parameters, $Source, $Srate,
$VPIFD, $APID, $TPID, $CA, $SID, $NID, $TID, $RID,
@Remarks ) = split( /:/, $lineBuffer );
# Line without Name or SID? Probably a new group:
if ( ! defined $Name || $Name eq '' ||
! defined $SID || $SID eq '' ) {
# Grouping line: we simply save the complete
# line contents now:
$channelData = {
'Name' => '',
'SID' => '',
'Group' => $lineBuffer,
};
}
else {
# Create Hash Reference
$channelData = {
'Name' => $Name,
'Frequency' =>$Frequency,
'Parameters' => $Parameters,
'Source' => $Source,
'Srate' => $Srate,
'VPIFD' => $VPIFD,
'APID' => $APID,
'TPID' => $TPID,
'CA' => $CA,
'SID' => $SID,
'NID' => $NID,
'TID' => $TID,
'RID' => $RID,
'Remark' => join( ":", @Remarks ),
};
}
# Done
return $channelData;
}
# ComputeChannelLine
#
# Takes the Reference of a Channel Data Hash and computes
# an new line for channel.conf. The line (including CR)
# will be returned.
#
# Parameter
# [0] Reference to Channel Data Hash
#
# Returns
# Hash Reference
#
sub ComputeChannelLine {
# Parameters
my $channelData = $_[0];
# Return
my $lineBuffer = "";
# Group Line Detection:
if ( $channelData->{'Name'} eq '' ||
$channelData->{'SID'} eq '' ) {
# Compute channel.conf group line
$lineBuffer = "$channelData->{Group}\n";
}
else {
# Compute channel.conf line format
$lineBuffer =
"$channelData->{Name}:$channelData->{Frequency}:$channelData->{Parameters}:".
"$channelData->{Source}:$channelData->{Srate}:$channelData->{VPIFD}:".
"$channelData->{APID}:$channelData->{TPID}:$channelData->{CA}:".
"$channelData->{SID}:$channelData->{NID}:$channelData->{TID}:$channelData->{RID}";
# Add additional Information if any
$lineBuffer .= ":$channelData->{Remark}" if ( $channelData->{Remark} ne ''
);
# End Of Line
$lineBuffer .= "\n";
}
# Done
return $lineBuffer;
}
# IsChannelData
#
# Return 1 if this Channel Data Hash contains data of
# a real channel. Return 0 if this Channel Data Hash
# is just a Grouping line ":Group".
#
# Parameter
# [0] Reference to Channel Data Hash
#
# Returns
# 0 or 1
#
sub IsChannelData {
# Parameters
my $channelData = $_[0];
# Real CHannel Data has a name and a SID as miminum
return ( ( $channelData->{'Name'} ne '' && $channelData->{'SID'} ne '' ) ? 1
: 0 );
}
# Usage
#
# Explains the usage of this script.
#
sub Usage {
print "\n";
print "USAGE:\n";
print "$0 <Source File> <Sort Order File> <Destination File>\n";
print "\n";
print "Sorts the VDR channels from the <Source File> according to the\n";
print "sort order given in the <Sort Order File> and writes them to\n";
print "the <Destination File>.\n";
print "\n";
print "HINTS:\n";
print "- The <Sort Order File> is usually an older channel.conf\n";
print "- All channels not mentioned in the <Sort Order File> are
appended.\n";
print "\n";
print "SAMPLE:\n";
print "$0 channels.conf channels.conf.my channels.conf.resorted\n";
print "\n";
}
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe vdr" as subject.
Home |
Main Index |
Thread Index