In <[EMAIL PROTECTED]>, Laz wrote:

> On Wednesday 14 February 2007 15:24, Andrew Herron wrote:
> > Does anyone know if the Logical Channel Numbers that are used in the UK
> > on Freeview DVB-T transmissions are currently handled by VDR in anyway?
> I'm pretty sure that they're currently ignored. I tend to hand edit my 
> channels.conf every now and then to make sure channels are in the corerct 
> order with their correct numbers.
> The scan utility can output a vdr-format channels.conf with the channel 
> numbers included, too.

I've had trouble in the past with VDR disagreeing with the format used
by the output of scan so I've written a script which compares VDR's
channels.conf with the output of scan with Freeview numbering and
outputs a new file with VDR's channel data but resorted and with the
Freeview numbering added.

It uses some file locations etc which are specific to Debian and my
local transmitter, but it can easily be altered by changing the
upper-case variables near the top of the script.

TH *
#!/usr/bin/env python

import subprocess
import sys
import time

""" Shuts down VDR, performs a scan, then updates VDR's channels.conf with
	Freeview numbering. """

INVOKE_RCD = "invoke-rc.d vdr"
SCAN_COMMAND = "scan -q -o vdr -e 4 -u " \
		+ "/usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-Rowridge"
VDR_CHANNELS_FILE = "/var/lib/vdr/channels.conf"

def scan():
	""" Runs SCAN_COMMAND and returns result as a list of lines. """
	print "Scanning"
	scan_proc = subprocess.Popen(SCAN_COMMAND, 0, None,
			None, subprocess.PIPE, None,
			None, False, True)
	result = scan_proc.wait()
	if result:
		raise Exception("scan failed with exit code %d" % result)
	return scan_proc.stdout.readlines()

def load_channels_as_lines(filename):
	fp = file(filename, 'r')
	lines = fp.readlines()
	return lines

def lines_to_dict(lines):
	""" Processes the lines and creates a dictionary keyed by channel name.
		Each value is [line, channel_number]. """
	dict = {}
	number = 1
	for l in lines:
		if l.startswith(':@'):
			number = int(l[2:].rstrip())
			name = l.split(':', 1)[0]
			if ';' in name:
				name = name.split(';', 1)[0]
			dict[name] = [l, number]
			number += 1
	return dict

def dict_to_sorted_lines(dict):
	""" Convert the dictionary back to lines, including :@n where necessary,
		all in the correct order. """
	# Create an intermediate list of [line, channel_number] for sorting
	sortable = []
	for v in dict.values():
	sortable.sort(key = lambda x: x[1])
	# Now generate lines in output format
	number = -1
	lines = []
	for l in sortable:
		if l[1] != number:
			number = l[1]
			lines.append(":@%d\n" % number)
		number += 1
	return lines

def renumber_old_from_new(old, new):
	""" For each entry in the old dict, this looks up the same channel name in
		the new dict and replaces the old channel number with the new one, but
		preserves all the other details from old. No return value; alters old
		in place. """
	for [k, old_val] in old.items():
		new_val = new.get(k)
		if new_val:
			old_val[1] = new_val[1]

def generate_new_lines():
	""" Call the various other functions to generate a nice new list of lines
		to save as VDR's channels.conf. """
	scan_lines = scan()
	vdr_lines = load_channels_as_lines(VDR_CHANNELS_FILE)
	scan_dict = lines_to_dict(scan_lines)
	vdr_dict = lines_to_dict(vdr_lines)
	renumber_old_from_new(vdr_dict, scan_dict)
	return dict_to_sorted_lines(vdr_dict)

def main():
	start_stop_vdr = "-s" in sys.argv
	if start_stop_vdr:
		print "Stopping VDR"
		print "Pausing"
	new_lines = generate_new_lines()
	fp = file(OUTPUT_FILE, 'w')
	if start_stop_vdr:
		print "Starting VDR"

if __name__ == '__main__':
vdr mailing list

Reply via email to