terminator/terminatorlib/configjson.py

181 lines
5.7 KiB
Python

from .util import dbg, err
from os import path
import json
import copy
from .config import Config
JSON_PROFILE_NAME = "__internal_json_profile__"
JSON_LAYOUT_NAME = "__internal_json_layout__"
class ConfigJson(object):
profile_to_use = 'default'
def get_profile_to_use(self):
return self.profile_to_use
def build_single_tab_layout(self, layoutjson, vertical):
dbg ('Budiling a single tab layout from json: %s ' % layoutjson)
result = {
'root': {
'type': 'Window'
}
}
self.build_container_layout(layoutjson, result, 'root', 0, vertical)
return result
def build_multi_tab_layout(self, layoutjson, vertical):
dbg ('Budiling multi tabs layout from json: %s ' % layoutjson)
tabs = {
'type': 'Notebook',
'parent': 'root',
'labels': []
}
result = {
'root': {
'type': 'Window'
},
'tabs': tabs
}
counter = 0
for tab in layoutjson:
tabs['labels'].append(tab)
self.build_container_layout(layoutjson[tab], result, 'tabs', counter, vertical)
counter += 1
return result
def build_terminal_layout(self, layoutjson, children, parent, order):
dbg ('Building a terminal from json: %s' % layoutjson)
def from_json(layout_name, json_name=None):
if json_name is None:
json_name = layout_name
if json_name in layoutjson:
children[parent + "." + str(order)][layout_name] = layoutjson[json_name]
children[parent + "." + str(order)] = {
'type': 'Terminal',
'order': order,
'parent': parent,
'profile': self.profile_to_use
}
from_json('command')
from_json('title')
def build_container_layout(self, layoutjson, children, parent, order, vertical):
if len(layoutjson) == 1:
layoutjson = layoutjson[0]
if 'children' in layoutjson:
self.build_container_layout(layoutjson['children'], children, parent, order, False if vertical else True)
else:
self.build_terminal_layout(layoutjson, children, parent, order)
return
dbg ('Building %s layout from json: %s' % ("vertical" if vertical else "horizontal", layoutjson))
counter = 0
actualparent = parent
for pane in layoutjson:
if counter < (len(layoutjson) - 1):
containername = parent + "." + str(order) + "." + str(counter)
ratio = (100 / (len(layoutjson) - counter)) / 100
if 'ratio' in pane:
ratio = pane['ratio']
children[containername] = {
'type': 'VPaned' if vertical else 'HPaned',
'order': order + counter,
'ratio': ratio,
'parent': actualparent
}
actualparent = containername
if 'children' in pane:
self.build_container_layout(pane['children'], children, containername, counter, False if vertical else True)
else:
self.build_terminal_layout(pane, children, containername, counter)
counter += 1
def get_layout(self, layoutjson):
try:
vertical = True
if "vertical" in layoutjson:
vertical = layoutjson["vertical"]
del layoutjson["vertical"]
if len(layoutjson) == 1:
firstitem = next(iter(layoutjson.values()))
result = self.build_single_tab_layout(firstitem, vertical)
else:
result = self.build_multi_tab_layout(layoutjson, vertical)
dbg('Json layout is: %s' % result)
return result
except Exception as ex:
err('Error building a layout from file %s' % ex)
return None
def get_profile(self, profilejson, baseprofile):
try:
result = copy.deepcopy(baseprofile)
result.update(profilejson)
dbg('Json profile is: %s' % result)
return result
except Exception as ex:
err('Error building a profile from json file %s' % ex)
return None
def read_config(self, jsonfile):
if not path.exists(jsonfile):
dbg("Json config file is missing %s" % jsonfile)
return None
dbg('Loading config json from a file: %s' % jsonfile)
layoutjson = None
try:
with open(jsonfile) as json_file:
layoutjson = json.load(json_file)
except Exception as ex:
err('Error loading config json file %s (%s)' % (jsonfile, ex))
return None
return layoutjson
def extend_config(self, jsonfile):
configjson = self.read_config(jsonfile)
if not configjson:
return None
config = Config()
if 'profile' in configjson:
profile = self.get_profile(configjson['profile'], config.base.profiles['default'])
if profile:
config.base.profiles[JSON_PROFILE_NAME] = profile
self.profile_to_use = JSON_PROFILE_NAME
if 'layout' in configjson:
layout = self.get_layout(configjson['layout'])
if layout:
config.base.layouts[JSON_LAYOUT_NAME] = layout
return JSON_LAYOUT_NAME
return None