support: updated the configuration migration script

This commit is contained in:
Adam Sutton 2013-11-14 12:59:20 +00:00
parent d8e1858fe7
commit c08b6e5c7f

View file

@ -1,41 +1,42 @@
#!/usr/bin/env python #!/usr/bin/env python
# #
# Load all channels/service info and attempt to create a translation from # Migration version 3 configuration to version 4
# the old setup to the new #
# Files that need updating:
# autorec/* : Auto-mapped by code
# dvr/log/* : Auto-mapped by code
# channels/* : map services
# dvb/* : map network/mux but nothing else
# epggrab/otamux : remove
#
# Create new "version" file to validate config version
#
#
# Imports
# #
import os, sys, re, json, glob import os, sys, re, json, glob
import pprint import pprint
from optparse import OptionParser
# Parse args #
root = '.' # Utilities
if len(sys.argv) > 1: #
root = sys.argv[1]
# Generate UUID # Generate UUID
def uuid (): def uuid ():
import uuid import uuid
return uuid.uuid4().hex return uuid.uuid4().hex
# Load channels #
chns = {} # DVB - input
for f in glob.glob(os.path.join(root, 'channels', '*')): #
try:
s = open(f).read()
d = json.loads(s)
chns[d['name']] = {
'svcs': [],
'name': d['name'] if 'name' in d else None,
'icon': d['icon'] if 'icon' in d else None,
'tags': d['tags'] if 'tags' in d else None,
'num' : d['channel_number'] if 'channel_number' in d else 0
}
except: pass
# Load adapters # Adapters
adps = {} def load_adapters ( path ):
for f in glob.glob(os.path.join(root, 'dvbadapters', '*')): adps = {}
try: for f in glob.glob(os.path.join(path, 'dvbadapters', '*')):
s = open(f).read() s = open(f).read()
d = json.loads(s) d = json.loads(s)
t = d['type'] t = d['type']
@ -47,206 +48,327 @@ for f in glob.glob(os.path.join(root, 'dvbadapters', '*')):
'type' : t, 'type' : t,
'nets' : {} 'nets' : {}
} }
except: pass
# Done
return adps
# Load muxes # Muxes
muxs = {} def load_muxes ( path, adps ):
for f in glob.glob(os.path.join(root, 'dvbmuxes', '*', '*')): maps = {
try: 'transportstreamid' : 'tsid',
'originalnetworkid' : 'onid',
'initialscan' : 'initscan',
'default_authority' : 'cridauth'
}
muxs = {}
for f in glob.glob(os.path.join(path, 'dvbmuxes', '*', '*')):
a = os.path.basename(os.path.dirname(f)) a = os.path.basename(os.path.dirname(f))
if a not in adps: continue if a not in adps: continue
t = adps[a]['type'] t = adps[a]['type']
s = open(f).read() s = open(f).read()
d = json.loads(s) d = json.loads(s)
k = '%s:%04X:%04X' % (t, d['originalnetworkid'], d['transportstreamid'])
m = { if not 'transportstreamid' in d: continue
'key' : k, tsid = d['transportstreamid']
'type': t, onid = d['originalnetworkid'] if 'transportstreamid' in d else None
'onid': d['originalnetworkid'],
'tsid': d['transportstreamid'], # Build
'freq': d['frequency'], m = {}
'symr': d['symbol_rate'] if 'symbol_rate' in d else None, for k in d:
'fec' : d['fec'] if 'fec' in d else None, if k in maps:
'fech': d['fec_hi'] if 'fec_hi' in d else None, m[maps[k]] = d[k]
'fecl': d['fec_lo'] if 'fec_lo' in d else None, else:
'gi' : d['guard_interval'] if 'guard_interval' in d else None, m[k] = d[k]
'hier': d['hierarchy'] if 'hierarchy' in d else None, m['type'] = t
'bw' : d['bandwidth'] if 'bandwidth' in d else None, m['key'] = k = '%s:%04X:%04X' % (t, onid, tsid)
'txm' : d['tranmission_mode'] if 'tranmission_mode' in d else None, m['svcs'] = {}
'mod' : d['modulation'] if 'modulation' in d else None,
'del' : d['delivery_system'] if 'delivery_system' in d else None, # Fixups
'cons': d['constellation'] if 'constellation' in d else None, if 'delivery_system' in m:
'pol' : d['polarisation'] if 'polarisation' in d else None, m['delivery_system'] = m['delivery_system'][4:]
'svcs': {} elif t == 'A':
} m['delivery_system'] = 'ATSC'
elif t == 'T':
m['delivery_system'] = 'DVBT'
elif t == 'C':
m['delivery_system'] = 'DVBC_ANNEX_AC'
elif t == 'S':
m['delivery_system'] = 'DVBS'
if 'polarisation' in m:
m['polarisation'] = m['polarisation'][0]
if 'modulation' in m and m['polarisation'] == 'PSK_8':
m['modulation'] = '8PSK'
if 'rolloff' in m:
m['rolloff'] = m['rolloff'][8:]
# Store
muxs[os.path.basename(f)] = m muxs[os.path.basename(f)] = m
# Network
n = None n = None
if 'satconf' in d: if 'satconf' in d:
n = d['satconf'] n = d['satconf']
if n not in adps[a]['nets']: if n not in adps[a]['nets']:
adps[a]['nets'][n] = {} adps[a]['nets'][n] = {}
adps[a]['nets'][n][k] = m adps[a]['nets'][n][k] = m
except Exception, e:
print e
raise e
pass
# Load servies # Done
svcs = {} return muxs
for f in glob.glob(os.path.join(root, 'dvbtransports', '*', '*')):
try: # Servies
def load_services ( path, muxs ):
svcs = {}
maps = {
'service_id' : 'sid',
'servicename' : 'svcname',
'stype' : 'dvb_servicetype',
'channel' : 'lcn',
'default_authority' : 'cridauth'
}
for f in glob.glob(os.path.join(path, 'dvbtransports', '*', '*')):
m = os.path.basename(os.path.dirname(f)) m = os.path.basename(os.path.dirname(f))
if m not in muxs: continue if m not in muxs: continue
# Load data
m = muxs[m] m = muxs[m]
s = open(f).read() s = open(f).read()
d = json.loads(s) d = json.loads(s)
if 'channelname' not in d or not d['channelname']: continue
k = '%s:%04X:%04X:%04X' % (m['type'], m['onid'], m['tsid'], d['service_id']) # Validate
m['svcs'][k] = d if 'service_id' not in d: continue
except Exception, e: if 'stream' in d: del d['stream']
print e
raise e # Map fields
pass s = {}
for k in d:
if k in maps:
s[maps[k]] = d[k]
else:
s[k] = d[k]
k = '%s:%04X:%04X:%04X' % (m['type'], m['onid'], m['tsid'], s['sid'])
m['svcs'][k] = svcs[k] = s
return svcs
#
# Channels
#
def load_channels ( path, nets ):
maps = {
'channel_number' : 'number',
'dvr_extra_time_pre' : 'dvr_pre_time',
'dvr_extra_time_pst' : 'dvr_pst_time',
}
chns = []
# Process channels
for f in glob.glob(os.path.join(path, 'channels', '*')):
# Load data
s = open(f).read()
d = json.loads(s)
c = { 'services' : [] }
# Map fields
for k in d:
if k in maps:
c[maps[k]] = d[k]
else:
c[k] = d[k]
# Find services
for n in nets:
for m in n['muxs']:
m = n['muxs'][m]
for s in m['svcs']:
s = m['svcs'][s]
if 'uuid' not in s: continue
if 'channelname' in s and s['channelname'] == c['name']:
c['services'].append(s['uuid'])
# Store
chns.append(c)
# Done
return chns
#
# Output
#
# Build networks # Build networks
nets = [] def build_networks ( adps, opts ):
for a in adps: nets = []
a = adps[a]
for m in a['nets']: # Process each adapter
m = a['nets'][m] for a in adps:
f = False a = adps[a]
for n in nets:
if n['type'] != a['type']: continue # Process each network
x = set(n['muxs'].keys()) for m in a['nets']:
y = set(m.keys()) m = a['nets'][m]
i = x.intersection(x, y) f = False
c = (2.0 * len(i)) / (len(x) + len(y))
#print 'comp %d %d %d %f' % (len(x), len(y), len(i), c) # Look for overlap and combine
if c > 0.5: for n in nets:
f = True if n['type'] != a['type']: continue
for k in m: x = set(n['muxs'].keys())
if k not in n['muxs']: y = set(m.keys())
n['muxs'][k] = m[k] i = x.intersection(x, y)
else: c = (2.0 * len(i)) / (len(x) + len(y))
n['muxs'][k]['svcs'].update(m[k]['svcs']) #print 'comp %d %d %d %f' % (len(x), len(y), len(i), c)
if not f: if c > 0.5:
n = { f = True
'type': a['type'], for k in m:
'muxs': m if k not in n['muxs']:
} n['muxs'][k] = m[k]
nets.append(n) else:
n['muxs'][k]['svcs'].update(m[k]['svcs'])
if not f:
n = {
'type': a['type'],
'muxs': m
}
nets.append(n)
# Set network name
i = 0
for n in nets:
i = i + 1
names = {}
for m in n['muxs']:
m = n['muxs'][m]
if 'network' not in m: continue
if m['network'] not in names:
names[m['network']] = 1
else:
names[m['network']] = 1 + names[m['network']]
name = None
for na in names:
if not name:
name = na
elif names[na] > names[name]:
name = na
if name:
n['name'] = name
else:
n['name'] = 'Network %s %d' % (n['type'], i)
# Done
return nets
# Output services
def output_services ( path, svcs, opts ):
ignore = { 'type', 'key', 'channelname', 'mapped' }
if not os.path.exists(path):
os.makedirs(path)
# Process services
for s in svcs:
s = svcs[s]
# Copy
d = {}
for k in s:
if k not in ignore:
d[k] = s[k]
# Output
u = uuid()
spath = os.path.join(path, u)
open(os.path.join(spath), 'w').write(json.dumps(d, indent=2))
s['uuid'] = u
# Output muxes
def output_muxes ( path, muxs, opts ):
ignore = [ 'type', 'key', 'svcs', 'network', 'quality', 'status' ]
# Process each
for m in muxs:
m = muxs[m]
# Copy
d = {}
for k in m:
if k not in ignore:
d[k] = m[k]
# Output
u = uuid()
mpath = os.path.join(path, u)
os.makedirs(mpath)
open(os.path.join(mpath, 'config'), 'w').write(json.dumps(d, indent=2))
# Services
output_services(os.path.join(mpath, 'services'), m['svcs'], opts)
# Output networks # Output networks
p = os.path.join(root, 'input', 'linuxdvb', 'networks') def output_networks ( path, nets, opts ):
if not os.path.exists(p):
os.makedirs(p) # Ensure dir exists
i = 0 path = os.path.join(path, 'input', 'linuxdvb', 'networks')
for n in nets: if not os.path.exists(path):
i = i + 1 os.makedirs(path)
# Write each network
for n in nets:
# Network config # Network config
if n['type'] == 'A': if n['type'] == 'A':
c = 'linuxdvb_network_atsc' c = 'linuxdvb_network_atsc'
else:
c = 'linuxdvb_network_dvb' + n['type'].lower()
d = {
'networkname' : 'Network %s %d' % (n['type'], i),
'nid' : 0,
'autodiscovery' : False,
'skipinitscan' : True,
'class' : c
}
u = uuid()
p2 = os.path.join(p, u)
os.mkdir(p2)
open(os.path.join(p2, 'config'), 'w').write(json.dumps(d))
# Process muxes
for m in n['muxs']:
m = n['muxs'][m]
d = {
'enabled' : True,
'frequency' : m['freq'],
'onid' : m['onid'],
'tsid' : m['tsid']
}
if m['type'] == 'C':
d['delsys'] = 'DVBC_ANNEX_AC'
d['symbolrate'] = m['symr']
d['fec'] = m['fec']
d['constellation'] = m['cons']
elif m['type'] == 'T':
d['delsys'] = 'DVBT'
d['bandwidth'] = m['bw']
d['constellation'] = m['cons']
d['tranmission_mode'] = m['txm']
d['guard_interval'] = m['gi']
d['hierarchy'] = m['hier']
d['fec_lo'] = m['fecl']
d['fec_hi'] = m['fech']
elif m['type'] == 'S':
d['symbolrate'] = m['symr']
d['fec'] = m['fec']
d['polarisation'] = m['pol'][0]
d['modulation'] = m['mod']
d['delsys'] = m['del'][4:]
d['inversion'] = 'AUTO'
if 'rolloff' in m:
d['rolloff'] = m['rolloff'][8:]
elif d['delsys'] == 'DVBS':
d['rolloff'] = '35'
else:
d['rolloff'] = 'AUTO'
if d['modulation'] == 'PSK_8':
d['modulation'] = '8PSK'
else: else:
d['delsys'] = 'ATSC' c = 'linuxdvb_network_dvb' + n['type'].lower()
d['constellation'] = m['cons'] d = {
u = uuid() 'networkname' : n['name'],
p3 = os.path.join(p2, 'muxes', u) 'nid' : 0,
os.makedirs(p3) 'autodiscovery' : False,
open(os.path.join(p3, 'config'), 'w').write(json.dumps(d)) 'skipinitscan' : True,
'class' : c
}
# Process services # Write
for s in m['svcs']: u = uuid()
s = m['svcs'][s] npath = os.path.join(path, u)
d = { os.mkdir(npath)
'enabled' : True, open(os.path.join(npath, 'config'), 'w').write(json.dumps(d, indent=2))
'sid' : s['service_id'],
'svcname' : s['servicename'] if 'servicename' in s else '',
'dvb_servicetype' : s['stype'] if 'stype' in s else 0
}
u = uuid()
p4 = os.path.join(p3, 'services')
if not os.path.exists(p4):
os.makedirs(p4)
open(os.path.join(p4, u), 'w').write(json.dumps(d))
# Find channel # Muxes
c = s['channelname'] if 'channelname' in s else None output_muxes(os.path.join(npath, 'muxes'), n['muxs'], opts)
#print 'SVC %s CHN %s' % (str(s), str(c))
if not c or c not in chns: # Channels
continue def output_channels ( path, chns, opts ):
c = chns[c]
c['svcs'].append(u)
# Output channels
if not os.path.exists(os.path.join(root, 'channel')):
os.mkdir(os.path.join(root, 'channel'))
for c in chns:
c = chns[c]
if 'name' not in c: continue
# Create UUID path = os.path.join(path, 'channel')
u = uuid() if not os.path.exists(path):
d = { os.makedirs(path)
'name' : c['name'],
'services' : c['svcs'] # Each channels
} for c in chns:
if c['icon']: u = uuid()
d['icon'] = c['icon']
if c['tags']: # Output
d['tags'] = c['tags'] open(os.path.join(path, u), 'w').write(json.dumps(c, indent=2))
if c['num']:
d['number'] = c['num'] #
open(os.path.join(root, 'channel', u), 'w').write(json.dumps(d)) # Main
#
optp = OptionParser()
optp.add_option('-o', '--overlap', type='float', default=0.5,
help='Percentage overlap at which networks considered same')
(opts,args) = optp.parse_args()
path = args[0]
adps = load_adapters(path)
muxs = load_muxes(path, adps)
svcs = load_services(path, muxs)
nets = build_networks(adps, opts)
output_networks(path, nets, opts)
chns = load_channels(path, nets)
output_channels(path, chns, opts)
sys.exit(0)