rewrite to python3

This commit is contained in:
Marcus Stoegbauer 2019-06-12 23:32:05 +02:00
parent 32aa6ff7d2
commit 2114d9a77d
10 changed files with 477 additions and 524 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/__pycache__/
*.pyc
build/
.idea/workspace.xml

4
.idea/misc.xml Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (pyuserconfig)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/pyuserconfig.iml" filepath="$PROJECT_DIR$/.idea/pyuserconfig.iml" />
</modules>
</component>
</project>

11
.idea/pyuserconfig.iml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (pyuserconfig)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,179 +1,156 @@
#!/usr/bin/env python #!/usr/bin/env python3
# encoding: utf-8 # encoding: utf-8
# $Id$
# $URL$
""" """
Tools.py Tools.py
Created by Marcus Stoegbauer on 2013-01-12. Created by Marcus Stoegbauer on 2013-01-12.
Copyright (c) 2013 __MyCompanyName__. All rights reserved.
""" """
import sys import sys
import os import os
import cfgfile import Userconfig.cfgfile as cfgfile
import re import re
import time import time
import shutil import shutil
import itertools
class Debug(object): class Debug(object):
verbose = 0 verbose = 0
def __init__(self, verbose=0): def __init__(self, verbose=0):
self.setverbose(verbose) self.setverbose(verbose)
# def __init__
def setverbose(self, verbose):
def setverbose(self, verbose): """docstring for setverbose"""
"""docstring for setverbose""" self.verbose = verbose
self.verbose = verbose
# def setverbose def addverbose(self):
"""docstring for setverbose"""
def addverbose(self): self.verbose += 1
"""docstring for setverbose"""
self.verbose += 1 def debug(self, out, level=0):
# def addverbose """docstring for debug"""
if self.verbose >= level:
def debug(self, out, level=0): print(out)
"""docstring for debug"""
if self.verbose >= level:
print out
# if level
# def debug
# class Debug
def error(out): def error(out):
"""Print error on stderr""" """Print error on stderr"""
print >> sys.stderr, str(out)+"\n" print(str(out)+"\n", file=sys.stderr)
# def error
def getConfig(filename):
"""reads filename as config, checks for DEST parameter and returns cfgfile object"""
ret = None
try:
ret = cfgfile.Conf(filename)
except:
error("Error reading config file %s" % filename)
return False
# try
# check for DEST parameter
if not ret.check("Main", "dest"):
error("No DEST in config file %s" % filename)
return False
# if no DEST
# replace $HOME with real home directory def get_config(filename):
if ret.get("Main", "dest") == "$HOME": """reads filename as config, checks for DEST parameter and returns cfgfile object"""
ret.set("Main", "dest", os.environ['HOME']) ret = None
# if $HOME try:
ret = cfgfile.Conf(filename)
# make sure DEST ends with / except:
if not ret.get("Main", "dest").endswith("/"): error("Error reading config file %s" % filename)
ret.set("Main", "dest", ret.get("Main", "dest")+"/") return False
# if not /
# check for DEST parameter
return ret if not ret.check("Main", "dest"):
# def getConfig error("No DEST in config file %s" % filename)
return False
# replace $HOME with real home directory
if ret.get("Main", "dest") == "$HOME":
ret.set("Main", "dest", os.environ['HOME'])
# make sure DEST ends with /
if not ret.get("Main", "dest").endswith("/"):
ret.set("Main", "dest", ret.get("Main", "dest")+"/")
return ret
def read_skip_comment(fp, commentstring): def read_skip_comment(fp, commentstring):
"""Read line from filehandle fp and skip all empty (whitespace) lines and lines starting with commentstring """Read line from filehandle fp and skip all empty (whitespace) lines and lines starting with commentstring
""" """
for line in fp: for line in fp:
line = line[:-1] line = line[:-1]
if (commentstring != "" and not re.match("^"+re.escape(commentstring), line)) and line !="" and not re.match("^\s+$", line): if (commentstring != "" and not re.match("^"+re.escape(commentstring), line)) and line !="" and not re.match("^\s+$", line):
yield line yield line
# if not match
# for line
# def read_skip_comment
def diff(destfile, tempfile, commentstring, debug): def diff(destfile, tempfile, commentstring, debug):
"""diff destfile and tempfile, returns True if files differ, False if they are the same""" """diff destfile and tempfile, returns True if files differ, False if they are the same"""
debug.debug("Diffing %s and %s" % (destfile, tempfile), 3) debug.debug("Diffing %s and %s" % (destfile, tempfile), 3)
if not os.path.isfile(destfile): if not os.path.isfile(destfile):
debug.debug("Destfile %s does not exist, returning True." % destfile, 3) debug.debug("Destfile %s does not exist, returning True." % destfile, 3)
# destfile does not exist -> copy tempfile over # destfile does not exist -> copy tempfile over
return True return True
# if not destfile # if not destfile
if not os.path.isfile(tempfile): if not os.path.isfile(tempfile):
# tempfile does not exist, this should never happen # tempfile does not exist, this should never happen
error("Temporary file %s does not exist, this should not happen." % tempfile) error("Temporary file %s does not exist, this should not happen." % tempfile)
sys.exit(1) sys.exit(1)
# if not tempfile # if not tempfile
fp1 = open(tempfile)
fp2 = open(destfile)
for line1, line2 in itertools.izip(read_skip_comment(fp1, commentstring), read_skip_comment(fp2, commentstring)):
if line1 != line2:
fp1.close()
fp2.close()
return True
# if differ
# for line
fp1.close()
fp2.close()
return False
# def diff
def userConfigGenerated(filename, cfg): fp1 = open(tempfile)
"""returns True if filename has been generated by userconfig, False else""" fp2 = open(destfile)
if not os.path.isfile(filename): for line1, line2 in zip(read_skip_comment(fp1, commentstring), read_skip_comment(fp2, commentstring)):
# filename does not exist, so it was not generated by userconfig if line1 != line2:
fp1.close()
fp2.close()
return True
# if differ
# for line
fp1.close()
fp2.close()
return False return False
# if not filename
if not cfg.check("Main","stamp"): def user_config_generated(filename, cfg):
# no STAMP in userconfig.cfg, so no way to check if file was generated by userconfig """returns True if filename has been generated by userconfig, False else"""
if not os.path.isfile(filename):
# filename does not exist, so it was not generated by userconfig
return False
if not cfg.check("Main","stamp"):
# no STAMP in userconfig.cfg, so no way to check if file was generated by userconfig
return False
fp = open(filename, "r")
for line in fp:
if re.search(re.escape(cfg.get("Main","stamp")), line):
return True
return False return False
# no STAMP
fp = open(filename, "r")
for line in fp:
if re.search(re.escape(cfg.get("Main","stamp")), line):
return True
# if search
# for line
return False
# def userConfigGenerated
def backupFile(filename, debug): def backup_file(filename, debug):
"""make backup of filename, returns True if backup is successful, False else""" """make backup of filename, returns True if backup is successful, False else"""
if os.path.isfile(filename): if os.path.isfile(filename):
debug.debug("%s exists, finding backup name." % filename, 3) debug.debug("%s exists, finding backup name." % filename, 3)
backupname = filename+".userconfig."+time.strftime("%F") backupname = filename+".userconfig."+time.strftime("%F")
testbackupname = backupname testbackupname = backupname
counter = 0 counter = 0
while os.path.isfile(testbackupname): while os.path.isfile(testbackupname):
counter+=1 counter+=1
testbackupname=backupname+"."+str(counter) testbackupname=backupname+"."+str(counter)
# while debug.debug("Renaming %s to %s" % (filename, testbackupname), 1)
debug.debug("Renaming %s to %s" % (filename, testbackupname), 1) os.rename(filename, testbackupname)
os.rename(filename, testbackupname) return True
return True
else:
debug.debug("%s does not exist, do not need backup." % filename, 3)
# if filename
return False
# def backupFile
def copyFile(sourcefile, destfile, debug):
"""copy sourcefile to destfile, returns True if successful, False else"""
if os.path.isfile(sourcefile):
# sourcefile exists
debug.debug("Source file %s exists, proceeding with copy." % sourcefile, 3)
if not os.path.isfile(destfile) or os.access(destfile, os.W_OK):
debug.debug("Copying %s to %s" % (sourcefile, destfile), 1)
shutil.copy(sourcefile, destfile)
return True
# destfile is writable
else: else:
debug.debug("Destination file %s does not exist or is not writable." % destfile, 3) debug.debug("%s does not exist, do not need backup." % filename, 3)
# if write ok return False
return False
# def copyFile
def copy_file(sourcefile, destfile, debug):
"""copy sourcefile to destfile, returns True if successful, False else"""
if os.path.isfile(sourcefile):
# sourcefile exists
debug.debug("Source file %s exists, proceeding with copy." % sourcefile, 3)
if not os.path.isfile(destfile) or os.access(destfile, os.W_OK):
debug.debug("Copying %s to %s" % (sourcefile, destfile), 1)
shutil.copy(sourcefile, destfile)
return True
# destfile is writable
else:
debug.debug("Destination file %s does not exist or is not writable." % destfile, 3)
return False

View File

@ -1,8 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python3
# encoding: utf-8 # encoding: utf-8
# #
# $Id$
# $URL$
""" """
cfgfile.py cfgfile.py
@ -10,87 +8,69 @@ cfgfile.py
Created by Marcus Stoegbauer on 2013-01-12. Created by Marcus Stoegbauer on 2013-01-12.
Copyright (c) 2013 __MyCompanyName__. All rights reserved. Copyright (c) 2013 __MyCompanyName__. All rights reserved.
""" """
import ConfigParser import configparser
import os import os
import re import re
class Conf(object): class Conf(object):
confobj = ConfigParser.RawConfigParser() confobj = configparser.RawConfigParser()
cfgfile = '' cfgfile = ''
debug = None debug = None
def __init__(self, filename = None):
"""if filename is set, open config file and initialize the ConfigParser
"""
self.confobj = ConfigParser.RawConfigParser()
if filename:
self.setfilename(filename)
# if filename
# def __init__
def setdebug(self, debug):
"""docstring for setdebug"""
self.debug = debug
# def setdebug
def setfilename(self, filename):
"""initialize the ConfigParser
"""
ret = self.confobj.read(filename)
if len(ret) == 0 or ret[0] != filename:
raise Exception('Cannot read config file ' + filename)
# if cannot read
self.cfgfile = filename
if self.debug:
self.debug.debug("Read config file %s" % filename, 2)
self.debug.debug("Replacing environment variables in %s." % filename, 3)
# if debug
for s in self.confobj.sections(): def __init__(self, filename=None):
for (i, val) in self.confobj.items(s): """if filename is set, open config file and initialize the ConfigParser
tempre = re.search("\$([A-Z]+)[^A-Z]*", val) """
if tempre: self.confobj = configparser.RawConfigParser()
varname = tempre.group(1) if filename:
if self.debug: self.setfilename(filename)
self.debug.debug("Found variable %s in %s." % (varname, i), 3)
# if debug
if os.environ.has_key(varname):
if self.debug:
self.debug.debug("%s exists in environment, replacing with %s." % (varname, os.environ[varname]), 3)
# if debug
self.set(s, i, val.replace("$"+varname, os.environ[varname]))
# if has_key
# if tempre
# for i
# for s
# def setfilename
def get(self, section, option): def setdebug(self, debug):
"""returns the value of option in section """docstring for setdebug"""
""" self.debug = debug
if not self.cfgfile:
raise Exception('No config file set')
# if not cfgfile
return self.confobj.get(section, option)
# def get
def set(self, section, option, value): def setfilename(self, filename):
"""docstring for update""" """initialize the ConfigParser
self.confobj.set(section, option, value) """
# def set ret = self.confobj.read(filename)
if len(ret) == 0 or ret[0] != filename:
raise Exception('Cannot read config file ' + filename)
self.cfgfile = filename
if self.debug:
self.debug.debug("Read config file %s" % filename, 2)
self.debug.debug("Replacing environment variables in %s." % filename, 3)
for s in self.confobj.sections():
for (i, val) in self.confobj.items(s):
tempre = re.search(r"\$([A-Z]+)[^A-Z]*", val)
if tempre:
varname = tempre.group(1)
if self.debug:
self.debug.debug("Found variable %s in %s." % (varname, i), 3)
if varname in os.environ:
if self.debug:
self.debug.debug("%s exists in environment, replacing with %s." %
(varname, os.environ[varname]), 3)
self.set(s, i, val.replace("$"+varname, os.environ[varname]))
def getitems(self, section): def get(self, section, option):
"""returns all items in section """returns the value of option in section
""" """
if not self.cfgfile: if not self.cfgfile:
raise Exception('No config file set') raise Exception('No config file set')
# if not cfgfile return self.confobj.get(section, option)
return self.confobj.items(section)
# def getitems
def check(self, section, option): def set(self, section, option, value):
"""checks for option in section""" """docstring for update"""
return self.confobj.has_option(section, option) self.confobj.set(section, option, value)
# def check
# class Conf def getitems(self, section):
"""returns all items in section
"""
if not self.cfgfile:
raise Exception('No config file set')
return self.confobj.items(section)
def check(self, section, option):
"""checks for option in section"""
return self.confobj.has_option(section, option)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# encoding: utf-8 # encoding: utf-8
# #
# $Id$ # $Id$
@ -11,68 +11,60 @@ Created by Marcus Stoegbauer on 2013-01-10.
Copyright (c) 2013 __MyCompanyName__. All rights reserved. Copyright (c) 2013 __MyCompanyName__. All rights reserved.
""" """
import sys
import os
import platform import platform
class checks(object):
def __init__(self):
pass
# def __init__
def getShortHostname(self):
"""docstring for getShortHostname"""
hostname = platform.node()
if hostname.count("."):
hostname = hostname.split(".")[0]
return hostname
# def getShortHostname
def __classesForHost__(self):
"""docstring for __classesForHost"""
classes = []
for c in dir(self):
if c.startswith("__"):
continue
# if __
ret = getattr(self, c)()
if len(ret) == 3:
classes.append(ret)
# for c
return map(lambda k: (k[1],k[2]), sorted(classes, key=lambda k: k[0]))
# def __classesForHost__
def header(self):
"""docstring for header"""
return (0, "", "header")
# def header
def footer(self):
"""docstring for footer"""
return (1000, "", "footer")
def all(self):
"""docstring for all"""
return (998, "", "all")
# def all
def arch(self):
"""docstring for arch"""
return(800, "Arch", platform.system())
# def arch
def hostname(self):
"""docstring for hostname"""
hostname = self.getShortHostname()
return(10, "Host", hostname)
# def hostname
def app(self): class Checks(object):
"""docstring for app""" def __init__(self):
hostname = self.getShortHostname() pass
if (hostname == "glitters"):
return(500, "", "rancid_hosts") def get_short_hostname(self):
else: """docstring for getShortHostname"""
return () hostname = platform.node()
# def app if hostname.count("."):
# def checks hostname = hostname.split(".")[0]
return hostname
# def getShortHostname
def __classes_for_host__(self):
"""docstring for __classesForHost"""
classes = []
for c in dir(self):
if c.startswith("__"):
continue
ret = getattr(self, c)()
if len(ret) == 3:
classes.append(ret)
return map(lambda k: (k[1], k[2]), sorted(classes, key=lambda k: k[0]))
def header(self):
"""docstring for header"""
return (0, "", "header")
def footer(self):
"""docstring for footer"""
return (1000, "", "footer")
def all(self):
"""docstring for all"""
return (998, "", "all")
def arch(self):
"""docstring for arch"""
return (800, "Arch", platform.system())
def hostname(self):
"""docstring for hostname"""
hostname = self.get_short_hostname()
return (10, "Host", hostname)
def app(self):
"""docstring for app"""
hostname = self.get_short_hostname()
if hostname == "glitters":
return (500, "", "rancid_hosts")
else:
return ()
# def app
# def checks

View File

@ -1,15 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python3
from distutils.core import setup from distutils.core import setup
import sys
import os
setup( name="userconfig", setup(name="userconfig",
version="0.1", version="0.1",
description="Generate config files for user home", description="Generate config files for user home",
author="Marcus Stoegbauer", author="Marcus Stoegbauer",
author_email="marcus@grmpf.org", author_email="marcus@grmpf.org",
packages=["Userconfig"], packages=["Userconfig"],
scripts = ["userconfig.py"], scripts=["userconfig.py"],
data_files = [ ('etc', [ 'userconfig.cfg' ]) ] data_files=[('etc', ['userconfig.cfg'])]
) )

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python3
# encoding: utf-8 # encoding: utf-8
# #
# $Id$ # $Id$
@ -8,7 +8,6 @@
userconfig.py userconfig.py
Created by Marcus Stoegbauer on 2013-01-10. Created by Marcus Stoegbauer on 2013-01-10.
Copyright (c) 2013 __MyCompanyName__. All rights reserved.
""" """
import sys import sys
@ -20,251 +19,225 @@ import time
# #
import Userconfig.cfgfile as cfgfile import Userconfig.cfgfile as cfgfile
from Userconfig.checks import checks from Userconfig.checks import Checks
import Userconfig.Tools as Tools import Userconfig.Tools as Tools
debug = Tools.Debug() debug = Tools.Debug()
classchecks = checks() classchecks = Checks()
cfg = cfgfile.Conf() cfg = cfgfile.Conf()
hostclasses = classchecks.__classesForHost__() hostclasses = classchecks.__classes_for_host__()
class Usage(Exception): help_message = """
def __init__(self, msg):
self.msg = msg
# def __init__
help_message = """
-h help -h help
-v verbose level (multiple v for higher level) -v verbose level (multiple v for higher level)
-c userconfig.cfg config file -c userconfig.cfg config file
""" """
# class Usage
class Usage(Exception):
def __init__(self, msg):
self.msg = msg
def workconf(directory, depth=2): def workconf(directory, depth=2):
"""walks through directory, collecting all filenames, returns list of all filenames""" """walks through directory, collecting all filenames, returns list of all filenames"""
dirs = os.listdir(directory) dirs = os.listdir(directory)
ret = [] ret = []
debug.debug("Finding files in directory %s." % directory, 4) debug.debug("Finding files in directory %s." % directory, 4)
for d in dirs: for d in dirs:
name = directory+"/"+d name = directory+"/"+d
if os.path.isdir(name): if os.path.isdir(name):
# fixme: create name if it does not exist # fixme: create name if it does not exist
workconf(name, depth+1) workconf(name, depth+1)
# if dir if name.endswith(".swp"):
if name.endswith(".swp"): continue
continue if d == ".svn":
if d == ".svn": continue
continue ret.append(name)
ret.append(name) debug.debug("Found file %s in directory %s" % (name, directory), 4)
debug.debug("Found file %s in directory %s" % (name, directory), 4) return ret
# if not .swp
# for d
return ret
# def workconf
def workdir(directory): def workdir(directory):
"""walks through all host classes, checking if the classes directory exists in directory """walks through all host classes, checking if the classes directory exists in directory
then collect all filenames within this directory and return a dict of all files for this then collect all filenames within this directory and return a dict of all files for this
directory directory
""" """
debug.debug("Working on directory %s" % directory, 3) debug.debug("Working on directory %s" % directory, 3)
# skip directory if no CONFIGFILE present # skip directory if no CONFIGFILE present
if not os.path.isfile(directory+"/"+cfg.get("Main", "configfile")): if not os.path.isfile(directory+"/"+cfg.get("Main", "configfile")):
debug.debug("No %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1) debug.debug("No %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1)
return ({},None) return {},None
# if not DEST
# get config file for directory
dirConfig = Tools.getConfig(directory+"/"+cfg.get("Main", "configfile"))
if not dirConfig:
debug.debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1)
return ({},None)
# if not dirConfig
destdir = dirConfig.get("Main","dest")
# destfiles is a dict of all files that will be created from the classes config
# key is the destination filename, values are all classes filenames that are used to
# build the file
destfiles = {}
# walk through all know classes in directory and find filenames
for h in hostclasses:
# build classes directory
if h[0] != "":
classdir = directory+"/"+h[0]+"_"+h[1]
else:
classdir = directory+"/"+h[1]
# if all
debug.debug("Looking for directory %s." % classdir, 4)
# if class directory exists
if os.path.isdir(classdir):
debug.debug("Found directory %s, getting files." % classdir, 4)
# get list of files within this class directory
tempfiles = workconf(classdir)
debug.debug("Got %d files: %s." % (len(tempfiles), str(tempfiles)), 4)
# put files into dict
for f in tempfiles:
destname = destdir+os.path.basename(f) # destination filename
if not destfiles.has_key(destname):
destfiles[destname] = []
# if not destname, create key with empty list
destfiles[destname].append(f) # append each file to dict
debug.debug("Added file to %s, now %d files: %s" % (destname, len(destfiles[destname]), destfiles[destname]), 4)
# for tempfiles
# if classdir
# for hostclasses
debug.debug("workdir: %s, Files: %s" % (directory, str(destfiles)), 3)
return (destfiles, dirConfig)
# def work
def buildFile(classfiles, destfile, commentstring): # get config file for directory
"""open all classfiles, assemble them and write the contents into a tempfile dir_config = Tools.get_config(directory + "/" + cfg.get("Main", "configfile"))
returns the name of tempfile""" if not dir_config:
content = [] debug.debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1)
if commentstring != "": return {},None
debug.debug("commentstring found, adding header.", 3)
content.append(commentstring + " " + cfg.get("Main","stamp") + " " + time.strftime("%+") + "\n") destdir = dir_config.get("Main","dest")
# if commentstring not empty # destfiles is a dict of all files that will be created from the classes config
# key is the destination filename, values are all classes filenames that are used to
for f in classfiles: # build the file
debug.debug("Merging %s." % f, 4) destfiles = {}
fp = open(f, "r")
filecontent = fp.read() # walk through all know classes in directory and find filenames
for h in hostclasses:
# build classes directory
if h[0] != "":
classdir = directory+"/"+h[0]+"_"+h[1]
else:
classdir = directory+"/"+h[1]
debug.debug("Looking for directory %s." % classdir, 4)
# if class directory exists
if os.path.isdir(classdir):
debug.debug("Found directory %s, getting files." % classdir, 4)
# get list of files within this class directory
tempfiles = workconf(classdir)
debug.debug("Got %d files: %s." % (len(tempfiles), str(tempfiles)), 4)
# put files into dict
for f in tempfiles:
destname = destdir+os.path.basename(f) # destination filename
if not destname in destfiles:
destfiles[destname] = []
destfiles[destname].append(f) # append each file to dict
debug.debug("Added file to %s, now %d files: %s" % (destname, len(destfiles[destname]), destfiles[destname]), 4)
debug.debug("workdir: %s, Files: %s" % (directory, str(destfiles)), 3)
return destfiles, dir_config
def build_file(classfiles, destfile, commentstring):
"""open all classfiles, assemble them and write the contents into a tempfile
returns the name of tempfile
:param classfiles:
:param destfile:
:param commentstring:
:return: str
"""
content = []
if commentstring != "":
debug.debug("commentstring found, adding header.", 3)
content.append(commentstring + " " + cfg.get("Main","stamp") + " " + time.strftime("%+") + "\n")
for f in classfiles:
debug.debug("Merging %s." % f, 4)
fp = open(f, "r")
filecontent = fp.read()
fp.close()
if commentstring == "":
# look for stamp in content, replace with real stamp
if re.search(re.escape(cfg.get("Main","stampreplace")), filecontent):
debug.debug("commentstring empty, replacing stamp in file", 3)
filecontent = re.sub(re.escape(cfg.get("Main","stampreplace")), cfg.get("Main","stamp"), filecontent)
content.append(filecontent)
(tempfd, tempfilename) = tempfile.mkstemp(prefix=os.path.basename(destfile), dir="/tmp")
try:
fp = os.fdopen(tempfd, "w")
except:
Tools.error("Cannot write to temporary file %s" % tempfilename)
os.remove(tempfilename)
return False
debug.debug("Writing merged files into tempfile %s." % tempfilename, 3)
for block in content:
fp.write(block)
fp.write("\n")
fp.close() fp.close()
if commentstring == "":
# look for stamp in content, replace with real stamp
if re.search(re.escape(cfg.get("Main","stampreplace")), filecontent):
debug.debug("commentstring empty, replacing stamp in file", 3)
filecontent = re.sub(re.escape(cfg.get("Main","stampreplace")), cfg.get("Main","stamp"), filecontent)
# if search
# if commentstring empty
content.append(filecontent)
# end f
(tempfd, tempfilename) = tempfile.mkstemp(prefix=os.path.basename(destfile), dir="/tmp")
fp = None return tempfilename
try:
fp = os.fdopen(tempfd, "w")
except:
Tools.error("Cannot write to temporary file %s" % tempfilename)
os.remove(tempfilename)
return False
# try
debug.debug("Writing merged files into tempfile %s." % tempfilename, 3)
for block in content:
fp.write(block)
fp.write("\n")
# for content
fp.close()
return tempfilename
# def buildFile
def processAllFiles(destfiles, dirConfig): def process_all_files(destfiles, dir_config):
"""processes all files in destfiles, generate files from classes, compare and copy if necessary""" """processes all files in destfiles, generate files from classes, compare and copy if necessary"""
for df in destfiles.keys(): for df in destfiles.keys():
debug.debug("Processing source files for %s." % df, 2) debug.debug("Processing source files for %s." % df, 2)
# assemble file to tmp # assemble file to tmp
commentstring = "" commentstring = ""
if dirConfig.check("Main", "commentstring"): if dir_config.check("Main", "commentstring"):
commentstring = dirConfig.get("Main", "commentstring") commentstring = dir_config.get("Main", "commentstring")
debug.debug("Found commentstring %s in %s" % (commentstring, df), 3) debug.debug("Found commentstring %s in %s" % (commentstring, df), 3)
# if COMMENTSTRNIG
tempfilename = build_file(destfiles[df], df, commentstring)
tempfilename = buildFile(destfiles[df], df, commentstring) if not tempfilename:
if not tempfilename: debug.debug("Error while creating temp file for %s, skipping." % df, 1)
debug.debug("Error while creating temp file for %s, skipping." % df, 1) continue
continue debug.debug("Merged files %s for %s into %s" % (str(destfiles[df]), df, tempfilename), 2)
# if not tempfilename
debug.debug("Merged files %s for %s into %s" % (str(destfiles[df]), df, tempfilename), 2) # diff assembled file and config file
if Tools.diff(df, tempfilename, commentstring, debug):
# diff assembled file and config file debug.debug("File %s has changed" % df, 0)
if Tools.diff(df, tempfilename, commentstring, debug): if not Tools.user_config_generated(df, cfg):
debug.debug("File %s has changed" % df, 0) debug.debug("%s not generated by userconfig, backing up." % df, 2)
if not Tools.userConfigGenerated(df, cfg): # file not generated from userconfig -> back up
debug.debug("%s not generated by userconfig, backing up." % df, 2) Tools.backup_file(df, debug)
# file not generated from userconfig -> back up # copy tmp file to real location
Tools.backupFile(df, debug) debug.debug("Copy %s to %s." % (tempfilename, df), 0)
# if not userConfigGenerated Tools.copy_file(tempfilename, df, debug)
# copy tmp file to real location # remove tmp
debug.debug("Copy %s to %s." % (tempfilename, df), 0) debug.debug("Removing temporary file %s." % tempfilename, 2)
Tools.copyFile(tempfilename, df, debug) os.remove(tempfilename)
# if diff
# remove tmp
debug.debug("Removing temporary file %s." % tempfilename, 2)
os.remove(tempfilename)
# for df
# def buildAllFiles
def main(): def main():
configfile = os.environ['HOME']+"/etc/userconfig.cfg" configfile = os.environ['HOME']+"/etc/userconfig.cfg"
global verbose
try:
try: try:
opts, args = getopt.getopt(sys.argv[1:], "hdc:v", ["help", "debug", "config="]) try:
except getopt.error, msg: opts, args = getopt.getopt(sys.argv[1:], "hdc:v", ["help", "debug", "config="])
raise Usage(msg) except getopt.GetoptError as msg:
# try getopt raise Usage(msg)
for option, value in opts: for option, value in opts:
if option == "-v": if option == "-v":
debug.addverbose() debug.addverbose()
if option in ("-h", "--help"): if option in ("-h", "--help"):
raise Usage(help_message) raise Usage(help_message)
if option in ("-d", "--debug.debug"): if option in ("-d", "--debug.debug"):
pass pass
if option in ("-c", "--config"): if option in ("-c", "--config"):
configfile = value configfile = value
# if except Usage as err:
# for option, value Tools.error(sys.argv[0].split("/")[-1] + ": " + str(err.msg))
except Usage, err: Tools.error("\t for help use --help")
Tools.error(sys.argv[0].split("/")[-1] + ": " + str(err.msg)) return 2
Tools.error("\t for help use --help")
return 2 debug.debug("Using configfile %s." % configfile, 1)
# try if not os.path.isfile(configfile):
Tools.error("No config file specified.")
debug.debug("Using configfile %s." % configfile, 1) return 2
if not os.path.isfile(configfile):
Tools.error( "No config file specified.") cfg.setdebug(debug)
return 2 cfg.setfilename(configfile)
# if configfile
cfg.setdebug(debug) debug.debug("Current host is in classes %s" % hostclasses, 1)
cfg.setfilename(configfile) configdir = cfg.get("Main", "configdir")
for d in os.listdir(configdir):
debug.debug("Current host is in classes %s" % hostclasses, 1) destfiles = {}
configdir = cfg.get("Main", "configdir") name = configdir+"/"+d
for d in os.listdir(configdir): debug.debug("Working in %s" % name, 1)
destfiles = {} if not os.path.isdir(name):
name = configdir+"/"+d debug.debug("%s is not a directory, skipping." % name, 3)
debug.debug("Working in %s" % name, 1) continue
if not os.path.isdir(name): elif d.startswith(".svn"):
debug.debug("%s is not a directory, skipping." % name, 3) debug.debug("%s is .svn, skipping." % name, 3)
continue continue
elif d.startswith(".svn"): elif os.path.isfile(name+"/.ignore"):
debug.debug("%s is .svn, skipping." % name, 3) debug.debug("%s contains file .ignore, skipping." % name, 3)
continue continue
elif os.path.isfile(name+"/.ignore"): else:
debug.debug("%s contains file .ignore, skipping." % name, 3) debug.debug("Processing files in %s" % name, 2)
continue (destfiles, dirConfig) = workdir(name)
else: if isinstance(destfiles, dict):
debug.debug("Processing files in %s" % name, 2) if len(destfiles.keys()) > 0:
(destfiles, dirConfig) = workdir(name) debug.debug("Building %d files: %s" % (len(destfiles.keys()), destfiles.keys()), 3)
if isinstance(destfiles, dict): process_all_files(destfiles, dirConfig)
if len(destfiles.keys()) > 0: else:
debug.debug("Building %d files: %s" % (len(destfiles.keys()), destfiles.keys()), 3) debug.debug("No files found for %s, skipping." % name, 1)
processAllFiles(destfiles, dirConfig)
# if > 0
else:
debug.debug("No files found for %s, skipping." % name, 1)
# if
# for d
# def main
if __name__ == '__main__': if __name__ == '__main__':
main() main()