import sys import os from userconfig.cfgfile import Conf import re import time import shutil class Debug: _verbose = 0 def __init__(self, verbose=0): self.set_verbose(verbose) def set_verbose(self, verbose): self._verbose = verbose def add_verbose(self): self._verbose += 1 def get_verbose(self): return self._verbose def stdout(self, out, level=0): if self._verbose >= level: print(out) def stderr(self, out, level=0): if self._verbose >= level: print(str(out)+"\n", file=sys.stderr) def get_config(filename, cfg): """reads filename as config, checks for DEST parameter and returns cfgfile object""" try: ret = Conf(filename) except ValueError: cfg.debug.stderr("Error reading config file %s" % filename) return False # check for DEST parameter if not ret.check(section="Main", option="dest"): cfg.debug.stderr("No dest in config file %s" % filename) return False # make sure DEST ends with / if not ret.get(section="Main", option="dest").endswith("/"): ret.set(section="Main", option="dest", value=ret.get(section="Main", option="dest")+"/") return ret def read_skip_comment(fp, commentstring): """Read line from filehandle fp and skip all empty (whitespace) lines and lines starting with commentstring """ for line in fp: line = line[:-1] if ((commentstring != "" and not re.match("^"+re.escape(commentstring), line)) and line != "" and not re.match(r"^\s+$", line)): yield line def diff(destfile, tempfile, commentstring, cfg): """diff destfile and tempfile, returns True if files differ, False if they are the same""" cfg.debug.stdout("Diffing %s and %s, comment: %s" % (destfile, tempfile, commentstring), 3) if not os.path.isfile(destfile): cfg.debug.stdout("Destfile %s does not exist, returning True." % destfile, 3) # destfile does not exist -> copy tempfile over return True # if not destfile if not os.path.isfile(tempfile): # tempfile does not exist, this should never happen cfg.debug.stderr("Temporary file %s does not exist, this should not happen." % tempfile) sys.exit(1) # if not tempfile fp1 = open(tempfile) fp2 = open(destfile) for line1, line2 in zip(read_skip_comment(fp1, commentstring), read_skip_comment(fp2, commentstring)): if line1 != line2: fp1.close() fp2.close() cfg.debug.stdout("%s differs, return true" % destfile, 3) return True # if differ # for line fp1.close() fp2.close() cfg.debug.stdout("%s is the same, return false" % destfile, 3) return False 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("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("stamp")), line): return True return False def backup_file(filename, cfg): """make backup of filename, returns True if backup is successful, False else""" if os.path.isfile(filename): cfg.debug.stdout("%s exists, finding backup name." % filename, 3) backupname = filename+".userconfig."+time.strftime("%F") testbackupname = backupname counter = 0 while os.path.isfile(testbackupname): counter += 1 testbackupname = backupname+"."+str(counter) cfg.debug.stdout("Renaming %s to %s" % (filename, testbackupname), 1) os.rename(filename, testbackupname) return True else: cfg.debug.stdout("%s does not exist, do not need backup." % filename, 3) return False def copy_file(sourcefile, destfile, cfg): """copy sourcefile to destfile, returns True if successful, False else""" if os.path.isfile(sourcefile): # sourcefile exists cfg.debug.stdout("Source file %s exists, proceeding with copy." % sourcefile, 3) if not os.path.isfile(destfile) or os.access(destfile, os.W_OK): cfg.debug.stdout("Copying %s to %s" % (sourcefile, destfile), 1) shutil.copy(sourcefile, destfile) return True # destfile is writable else: cfg.debug.stdout("Destination file %s does not exist or is not writable." % destfile, 3) return False