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 generated 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 generated 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 generated 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 generated 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): def addverbose(self):
"""docstring for setverbose""" """docstring for setverbose"""
self.verbose += 1 self.verbose += 1
# def addverbose
def debug(self, out, level=0):
"""docstring for debug"""
if self.verbose >= level:
print(out)
def debug(self, out, level=0):
"""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 def get_config(filename):
if not ret.check("Main", "dest"): """reads filename as config, checks for DEST parameter and returns cfgfile object"""
error("No DEST in config file %s" % filename) ret = None
return False try:
# if no DEST ret = cfgfile.Conf(filename)
except:
error("Error reading config file %s" % filename)
return False
# replace $HOME with real home directory # check for DEST parameter
if ret.get("Main", "dest") == "$HOME": if not ret.check("Main", "dest"):
ret.set("Main", "dest", os.environ['HOME']) error("No DEST in config file %s" % filename)
# if $HOME return False
# make sure DEST ends with / # replace $HOME with real home directory
if not ret.get("Main", "dest").endswith("/"): if ret.get("Main", "dest") == "$HOME":
ret.set("Main", "dest", ret.get("Main", "dest")+"/") ret.set("Main", "dest", os.environ['HOME'])
# if not /
# make sure DEST ends with /
if not ret.get("Main", "dest").endswith("/"):
ret.set("Main", "dest", ret.get("Main", "dest")+"/")
return ret
return ret
# def getConfig
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) fp1 = open(tempfile)
fp2 = open(destfile) fp2 = open(destfile)
for line1, line2 in itertools.izip(read_skip_comment(fp1, commentstring), read_skip_comment(fp2, commentstring)): for line1, line2 in zip(read_skip_comment(fp1, commentstring), read_skip_comment(fp2, commentstring)):
if line1 != line2: if line1 != line2:
fp1.close() fp1.close()
fp2.close() fp2.close()
return True return True
# if differ # if differ
# for line # for line
fp1.close() fp1.close()
fp2.close() fp2.close()
return False
# def diff
def userConfigGenerated(filename, cfg):
"""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 return False
# if not filename
if not cfg.check("Main","stamp"):
# no STAMP in userconfig.cfg, so no way to check if file was generated by userconfig def user_config_generated(filename, cfg):
"""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: def backup_file(filename, debug):
if re.search(re.escape(cfg.get("Main","stamp")), line): """make backup of filename, returns True if backup is successful, False else"""
return True if os.path.isfile(filename):
# if search debug.debug("%s exists, finding backup name." % filename, 3)
# for line backupname = filename+".userconfig."+time.strftime("%F")
return False testbackupname = backupname
# def userConfigGenerated counter = 0
while os.path.isfile(testbackupname):
def backupFile(filename, debug): counter+=1
"""make backup of filename, returns True if backup is successful, False else""" testbackupname=backupname+"."+str(counter)
if os.path.isfile(filename): debug.debug("Renaming %s to %s" % (filename, testbackupname), 1)
debug.debug("%s exists, finding backup name." % filename, 3) os.rename(filename, testbackupname)
backupname = filename+".userconfig."+time.strftime("%F") return True
testbackupname = backupname
counter = 0
while os.path.isfile(testbackupname):
counter+=1
testbackupname=backupname+"."+str(counter)
# while
debug.debug("Renaming %s to %s" % (filename, testbackupname), 1)
os.rename(filename, testbackupname)
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): def __init__(self, filename=None):
"""if filename is set, open config file and initialize the ConfigParser """if filename is set, open config file and initialize the ConfigParser
""" """
self.confobj = ConfigParser.RawConfigParser() self.confobj = configparser.RawConfigParser()
if filename: if filename:
self.setfilename(filename) self.setfilename(filename)
# if filename
# def __init__
def setdebug(self, debug): def setdebug(self, debug):
"""docstring for setdebug""" """docstring for setdebug"""
self.debug = debug self.debug = debug
# def setdebug
def setfilename(self, filename): def setfilename(self, filename):
"""initialize the ConfigParser """initialize the ConfigParser
""" """
ret = self.confobj.read(filename) ret = self.confobj.read(filename)
if len(ret) == 0 or ret[0] != filename: if len(ret) == 0 or ret[0] != filename:
raise Exception('Cannot read config file ' + filename) raise Exception('Cannot read config file ' + filename)
# if cannot read self.cfgfile = filename
self.cfgfile = filename if self.debug:
if self.debug: self.debug.debug("Read config file %s" % filename, 2)
self.debug.debug("Read config file %s" % filename, 2) self.debug.debug("Replacing environment variables in %s." % filename, 3)
self.debug.debug("Replacing environment variables in %s." % filename, 3)
# if debug
for s in self.confobj.sections(): for s in self.confobj.sections():
for (i, val) in self.confobj.items(s): for (i, val) in self.confobj.items(s):
tempre = re.search("\$([A-Z]+)[^A-Z]*", val) tempre = re.search(r"\$([A-Z]+)[^A-Z]*", val)
if tempre: if tempre:
varname = tempre.group(1) varname = tempre.group(1)
if self.debug: if self.debug:
self.debug.debug("Found variable %s in %s." % (varname, i), 3) self.debug.debug("Found variable %s in %s." % (varname, i), 3)
# if debug if varname in os.environ:
if os.environ.has_key(varname): if self.debug:
if self.debug: self.debug.debug("%s exists in environment, replacing with %s." %
self.debug.debug("%s exists in environment, replacing with %s." % (varname, os.environ[varname]), 3) (varname, os.environ[varname]), 3)
# if debug self.set(s, i, val.replace("$"+varname, os.environ[varname]))
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 get(self, section, option):
"""returns the value of option 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.get(section, option)
# def get
def set(self, section, option, value): def set(self, section, option, value):
"""docstring for update""" """docstring for update"""
self.confobj.set(section, option, value) self.confobj.set(section, option, value)
# def set
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 getitems(self, section): def check(self, section, option):
"""returns all items in section """checks for option in section"""
""" return self.confobj.has_option(section, option)
if not self.cfgfile:
raise Exception('No config file set')
# if not cfgfile
return self.confobj.items(section)
# def getitems
def check(self, section, option):
"""checks for option in section"""
return self.confobj.has_option(section, option)
# def check
# class Conf

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): class Checks(object):
"""docstring for getShortHostname""" def __init__(self):
hostname = platform.node() pass
if hostname.count("."):
hostname = hostname.split(".")[0]
return hostname
# def getShortHostname
def __classesForHost__(self): def get_short_hostname(self):
"""docstring for __classesForHost""" """docstring for getShortHostname"""
classes = [] hostname = platform.node()
for c in dir(self): if hostname.count("."):
if c.startswith("__"): hostname = hostname.split(".")[0]
continue return hostname
# 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): # def getShortHostname
"""docstring for header"""
return (0, "", "header")
# def header
def footer(self): def __classes_for_host__(self):
"""docstring for footer""" """docstring for __classesForHost"""
return (1000, "", "footer") 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 all(self): def header(self):
"""docstring for all""" """docstring for header"""
return (998, "", "all") return (0, "", "header")
# def all
def arch(self): def footer(self):
"""docstring for arch""" """docstring for footer"""
return(800, "Arch", platform.system()) return (1000, "", "footer")
# def arch
def hostname(self): def all(self):
"""docstring for hostname""" """docstring for all"""
hostname = self.getShortHostname() return (998, "", "all")
return(10, "Host", hostname)
# def hostname
def app(self): def arch(self):
"""docstring for app""" """docstring for arch"""
hostname = self.getShortHostname() return (800, "Arch", platform.system())
if (hostname == "glitters"):
return(500, "", "rancid_hosts") def hostname(self):
else: """docstring for hostname"""
return () hostname = self.get_short_hostname()
# def app 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 # 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 # get config file for directory
dirConfig = Tools.getConfig(directory+"/"+cfg.get("Main", "configfile")) dir_config = Tools.get_config(directory + "/" + cfg.get("Main", "configfile"))
if not dirConfig: if not dir_config:
debug.debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1) debug.debug("Cannot read %s in %s, skipping." % (cfg.get("Main", "configfile"), directory), 1)
return ({},None) return {},None
# if not dirConfig
destdir = dirConfig.get("Main","dest") destdir = dir_config.get("Main","dest")
# destfiles is a dict of all files that will be created from the classes config # 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 # key is the destination filename, values are all classes filenames that are used to
# build the file # build the file
destfiles = {} destfiles = {}
# walk through all know classes in directory and find filenames # walk through all know classes in directory and find filenames
for h in hostclasses: for h in hostclasses:
# build classes directory # build classes directory
if h[0] != "": if h[0] != "":
classdir = directory+"/"+h[0]+"_"+h[1] classdir = directory+"/"+h[0]+"_"+h[1]
else: else:
classdir = directory+"/"+h[1] classdir = directory+"/"+h[1]
# if all debug.debug("Looking for directory %s." % classdir, 4)
debug.debug("Looking for directory %s." % classdir, 4) # if class directory exists
# if class directory exists if os.path.isdir(classdir):
if os.path.isdir(classdir): debug.debug("Found directory %s, getting files." % classdir, 4)
debug.debug("Found directory %s, getting files." % classdir, 4) # get list of files within this class directory
# get list of files within this class directory tempfiles = workconf(classdir)
tempfiles = workconf(classdir) debug.debug("Got %d files: %s." % (len(tempfiles), str(tempfiles)), 4)
debug.debug("Got %d files: %s." % (len(tempfiles), str(tempfiles)), 4) # put files into dict
# put files into dict for f in tempfiles:
for f in tempfiles: destname = destdir+os.path.basename(f) # destination filename
destname = destdir+os.path.basename(f) # destination filename if not destname in destfiles:
if not destfiles.has_key(destname): destfiles[destname] = []
destfiles[destname] = [] destfiles[destname].append(f) # append each file to dict
# if not destname, create key with empty list debug.debug("Added file to %s, now %d files: %s" % (destname, len(destfiles[destname]), destfiles[destname]), 4)
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) debug.debug("workdir: %s, Files: %s" % (directory, str(destfiles)), 3)
return (destfiles, dirConfig) return destfiles, dir_config
# def work
def buildFile(classfiles, destfile, commentstring):
"""open all classfiles, assemble them and write the contents into a tempfile
returns the name of tempfile"""
content = []
if commentstring != "":
debug.debug("commentstring found, adding header.", 3)
content.append(commentstring + " " + cfg.get("Main","stamp") + " " + time.strftime("%+") + "\n")
# if commentstring not empty
for f in classfiles: def build_file(classfiles, destfile, commentstring):
debug.debug("Merging %s." % f, 4) """open all classfiles, assemble them and write the contents into a tempfile
fp = open(f, "r") returns the name of tempfile
filecontent = fp.read() :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") return tempfilename
fp = None
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 process_all_files(destfiles, dir_config):
# def buildFile """processes all files in destfiles, generate files from classes, compare and copy if necessary"""
for df in destfiles.keys():
debug.debug("Processing source files for %s." % df, 2)
# assemble file to tmp
commentstring = ""
if dir_config.check("Main", "commentstring"):
commentstring = dir_config.get("Main", "commentstring")
debug.debug("Found commentstring %s in %s" % (commentstring, df), 3)
def processAllFiles(destfiles, dirConfig): tempfilename = build_file(destfiles[df], df, commentstring)
"""processes all files in destfiles, generate files from classes, compare and copy if necessary""" if not tempfilename:
for df in destfiles.keys(): debug.debug("Error while creating temp file for %s, skipping." % df, 1)
debug.debug("Processing source files for %s." % df, 2) continue
# assemble file to tmp debug.debug("Merged files %s for %s into %s" % (str(destfiles[df]), df, tempfilename), 2)
commentstring = ""
if dirConfig.check("Main", "commentstring"):
commentstring = dirConfig.get("Main", "commentstring")
debug.debug("Found commentstring %s in %s" % (commentstring, df), 3)
# if COMMENTSTRNIG
tempfilename = buildFile(destfiles[df], df, commentstring) # diff assembled file and config file
if not tempfilename: if Tools.diff(df, tempfilename, commentstring, debug):
debug.debug("Error while creating temp file for %s, skipping." % df, 1) debug.debug("File %s has changed" % df, 0)
continue if not Tools.user_config_generated(df, cfg):
# if not tempfilename debug.debug("%s not generated by userconfig, backing up." % df, 2)
debug.debug("Merged files %s for %s into %s" % (str(destfiles[df]), df, tempfilename), 2) # file not generated from userconfig -> back up
Tools.backup_file(df, debug)
# copy tmp file to real location
debug.debug("Copy %s to %s." % (tempfilename, df), 0)
Tools.copy_file(tempfilename, df, debug)
# remove tmp
debug.debug("Removing temporary file %s." % tempfilename, 2)
os.remove(tempfilename)
# diff assembled file and config file
if Tools.diff(df, tempfilename, commentstring, debug):
debug.debug("File %s has changed" % df, 0)
if not Tools.userConfigGenerated(df, cfg):
debug.debug("%s not generated by userconfig, backing up." % df, 2)
# file not generated from userconfig -> back up
Tools.backupFile(df, debug)
# if not userConfigGenerated
# copy tmp file to real location
debug.debug("Copy %s to %s." % (tempfilename, df), 0)
Tools.copyFile(tempfilename, df, debug)
# 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
# try
debug.debug("Using configfile %s." % configfile, 1) debug.debug("Using configfile %s." % configfile, 1)
if not os.path.isfile(configfile): if not os.path.isfile(configfile):
Tools.error( "No config file specified.") Tools.error("No config file specified.")
return 2 return 2
# if configfile
cfg.setdebug(debug)
cfg.setfilename(configfile)
debug.debug("Current host is in classes %s" % hostclasses, 1) cfg.setdebug(debug)
configdir = cfg.get("Main", "configdir") cfg.setfilename(configfile)
for d in os.listdir(configdir):
destfiles = {} debug.debug("Current host is in classes %s" % hostclasses, 1)
name = configdir+"/"+d configdir = cfg.get("Main", "configdir")
debug.debug("Working in %s" % name, 1) for d in os.listdir(configdir):
if not os.path.isdir(name): destfiles = {}
debug.debug("%s is not a directory, skipping." % name, 3) name = configdir+"/"+d
continue debug.debug("Working in %s" % name, 1)
elif d.startswith(".svn"): if not os.path.isdir(name):
debug.debug("%s is .svn, skipping." % name, 3) debug.debug("%s is not a directory, skipping." % name, 3)
continue continue
elif os.path.isfile(name+"/.ignore"): elif d.startswith(".svn"):
debug.debug("%s contains file .ignore, skipping." % name, 3) debug.debug("%s is .svn, skipping." % name, 3)
continue continue
else: elif os.path.isfile(name+"/.ignore"):
debug.debug("Processing files in %s" % name, 2) debug.debug("%s contains file .ignore, skipping." % name, 3)
(destfiles, dirConfig) = workdir(name) continue
if isinstance(destfiles, dict): else:
if len(destfiles.keys()) > 0: debug.debug("Processing files in %s" % name, 2)
debug.debug("Building %d files: %s" % (len(destfiles.keys()), destfiles.keys()), 3) (destfiles, dirConfig) = workdir(name)
processAllFiles(destfiles, dirConfig) if isinstance(destfiles, dict):
# if > 0 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) process_all_files(destfiles, dirConfig)
# if else:
# for d debug.debug("No files found for %s, skipping." % name, 1)
# def main
if __name__ == '__main__': if __name__ == '__main__':
main() main()