264 lines
8.4 KiB
Python
264 lines
8.4 KiB
Python
from __future__ import print_function
|
|
|
|
import os
|
|
import re
|
|
|
|
from sys import platform
|
|
from configtool.data import (
|
|
defineValueFormat,
|
|
defineBoolFormat,
|
|
reHelpTextStart,
|
|
reHelpTextEnd,
|
|
reDefine,
|
|
reDefineBL,
|
|
reDefQS,
|
|
reDefQSm,
|
|
reDefQSm2,
|
|
reDefBool,
|
|
reDefBoolBL,
|
|
)
|
|
|
|
|
|
class Printer:
|
|
def __init__(self, settings):
|
|
self.configFile = None
|
|
|
|
self.cfgValues = {}
|
|
self.settings = settings
|
|
self.cfgDir = os.path.join(self.settings.folder, "configtool")
|
|
|
|
def getValues(self):
|
|
vars = [(x, self.cfgValues[x]) for x in self.cfgValues]
|
|
return dict(vars)
|
|
|
|
def hasData(self):
|
|
return self.configFile != None
|
|
|
|
def getFileName(self):
|
|
return self.configFile
|
|
|
|
def loadConfigFile(self, fn):
|
|
cfgFn = os.path.join(self.cfgDir, "printer.generic.h")
|
|
try:
|
|
self.cfgBuffer = list(open(cfgFn))
|
|
except:
|
|
return False, cfgFn
|
|
|
|
try:
|
|
self.userBuffer = list(open(fn))
|
|
except:
|
|
return False, fn
|
|
|
|
self.configFile = fn
|
|
|
|
gatheringHelpText = False
|
|
helpTextString = ""
|
|
helpKey = None
|
|
|
|
self.cfgValues = {}
|
|
self.cfgNames = []
|
|
self.helpText = {}
|
|
|
|
prevLines = ""
|
|
for ln in self.cfgBuffer:
|
|
if gatheringHelpText:
|
|
if reHelpTextEnd.match(ln):
|
|
gatheringHelpText = False
|
|
helpTextString = helpTextString.strip()
|
|
# Keep paragraphs with double-newline.
|
|
helpTextString = helpTextString.replace("\n\n ", "\n\n")
|
|
# Keep indented lines, typically a list.
|
|
helpTextString = helpTextString.replace("\n\n ", "\n\n ")
|
|
helpTextString = helpTextString.replace("\n ", "\n\n ")
|
|
# Remove all other newlines and indents.
|
|
helpTextString = helpTextString.replace("\n ", " ")
|
|
hk = helpKey.split()
|
|
for k in hk:
|
|
self.helpText[k] = helpTextString
|
|
helpTextString = ""
|
|
helpKey = None
|
|
continue
|
|
else:
|
|
helpTextString += ln
|
|
continue
|
|
|
|
m = reHelpTextStart.match(ln)
|
|
if m:
|
|
t = m.groups()
|
|
gatheringHelpText = True
|
|
helpKey = t[0]
|
|
continue
|
|
|
|
if ln.rstrip().endswith("\\"):
|
|
prevLines += ln.rstrip()[:-1]
|
|
continue
|
|
|
|
if prevLines != "":
|
|
ln = prevLines + ln
|
|
prevLines = ""
|
|
|
|
self.parseDefineName(ln)
|
|
self.parseDefineValue(ln)
|
|
|
|
# Set all boolean generic configuration items to False, so items not yet
|
|
# existing in the user configuration default to disabled.
|
|
for k in self.cfgValues.keys():
|
|
if isinstance(self.cfgValues[k], bool):
|
|
self.cfgValues[k] = False
|
|
|
|
# Read the user configuration. This usually overwrites all of the items
|
|
# read above, but not those missing in the user configuration, e.g.
|
|
# when reading an older config.
|
|
gatheringHelpText = False
|
|
prevLines = ""
|
|
for ln in self.userBuffer:
|
|
if gatheringHelpText:
|
|
if reHelpTextEnd.match(ln):
|
|
gatheringHelpText = False
|
|
continue
|
|
|
|
if reHelpTextStart.match(ln):
|
|
gatheringHelpText = True
|
|
continue
|
|
|
|
if ln.rstrip().endswith("\\"):
|
|
prevLines += ln.rstrip()[:-1]
|
|
continue
|
|
|
|
if prevLines != "":
|
|
ln = prevLines + ln
|
|
prevLines = ""
|
|
|
|
self.parseDefineValue(ln)
|
|
|
|
# Parsing done. All parsed stuff is now in these array and dicts.
|
|
if self.settings.verbose >= 2:
|
|
print(self.cfgValues) # #defines with a value.
|
|
print(self.cfgNames) # Names found in the generic file.
|
|
if self.settings.verbose >= 3:
|
|
print(self.helpText)
|
|
|
|
return True, None
|
|
|
|
def parseDefineName(self, ln):
|
|
m = reDefBool.search(ln)
|
|
if m:
|
|
t = m.groups()
|
|
if len(t) == 1:
|
|
self.cfgNames.append(t[0])
|
|
return True
|
|
|
|
return False
|
|
|
|
def parseDefineValue(self, ln):
|
|
m = reDefQS.search(ln)
|
|
if m:
|
|
t = m.groups()
|
|
if len(t) == 2:
|
|
m = reDefQSm.search(ln)
|
|
if m:
|
|
t = m.groups()
|
|
tt = re.findall(reDefQSm2, t[1])
|
|
if len(tt) == 1 and (t[0] in self.cfgNames):
|
|
self.cfgValues[t[0]] = tt[0], True
|
|
return True
|
|
elif len(tt) > 1 and (t[0] in self.cfgNames):
|
|
self.cfgValues[t[0]] = tt, True
|
|
return True
|
|
|
|
m = reDefine.search(ln)
|
|
if m:
|
|
t = m.groups()
|
|
if len(t) == 2 and (t[0] in self.cfgNames):
|
|
if reDefineBL.search(ln):
|
|
self.cfgValues[t[0]] = t[1], True
|
|
else:
|
|
self.cfgValues[t[0]] = t[1], False
|
|
return True
|
|
|
|
m = reDefBool.search(ln)
|
|
if m:
|
|
t = m.groups()
|
|
# Accept booleans, but not those for which a value exists already.
|
|
# Booleans already existing as values are most likely misconfigured
|
|
# manual edits (or result of a bug).
|
|
if (
|
|
len(t) == 1
|
|
and t[0] in self.cfgNames
|
|
and not (
|
|
t[0] in self.cfgValues and isinstance(self.cfgValues[t[0]], tuple)
|
|
)
|
|
):
|
|
if reDefBoolBL.search(ln):
|
|
self.cfgValues[t[0]] = True
|
|
else:
|
|
self.cfgValues[t[0]] = False
|
|
return True
|
|
|
|
return False
|
|
|
|
def saveConfigFile(self, path, values):
|
|
if not values:
|
|
values = self.cfgValues
|
|
|
|
if self.settings.verbose >= 1:
|
|
print("Saving printer: %s." % path)
|
|
if self.settings.verbose >= 2:
|
|
print(values)
|
|
|
|
fp = open(path, "w")
|
|
self.configFile = path
|
|
|
|
for ln in self.cfgBuffer:
|
|
m = reDefine.match(ln)
|
|
if m:
|
|
t = m.groups()
|
|
if len(t) == 2 and t[0] in values.keys():
|
|
v = values[t[0]]
|
|
self.cfgValues[t[0]] = v
|
|
if v[1] == False:
|
|
fp.write("//")
|
|
fp.write(defineValueFormat % (t[0], v[0]))
|
|
else:
|
|
if t[0] == "CANNED_CYCLE":
|
|
# Known to be absent in the GUI. Worse, this value is replaced
|
|
# by the one in the metadata file.
|
|
#
|
|
# TODO: make value reading above recognize wether this value is
|
|
# commented out or not. Reading the value its self works
|
|
# already. Hint: it's the rule using reDefQS, reDefQSm, etc.
|
|
#
|
|
# TODO: add a multiline text field in the GUI to deal with this.
|
|
#
|
|
# TODO: write this value out properly. In /* comments */, if
|
|
# disabled.
|
|
#
|
|
# TODO: currently, the lines beyond the ones with the #define are
|
|
# treated like arbitrary comments. Having the former TODOs
|
|
# done, this will lead to duplicates.
|
|
fp.write(ln)
|
|
else:
|
|
print("Value key " + t[0] + " not found in GUI.")
|
|
|
|
continue
|
|
|
|
m = reDefBoolBL.match(ln)
|
|
if m:
|
|
t = m.groups()
|
|
if len(t) == 1 and t[0] in values.keys():
|
|
v = values[t[0]]
|
|
self.cfgValues[t[0]] = v
|
|
if v == "" or v == False:
|
|
fp.write("//")
|
|
fp.write(defineBoolFormat % t[0])
|
|
else:
|
|
print("Boolean key " + t[0] + " not found in GUI.")
|
|
|
|
continue
|
|
|
|
fp.write(ln)
|
|
|
|
fp.close()
|
|
|
|
return True
|