Commit 18491601 authored by Daniel Armbruster's avatar Daniel Armbruster Committed by thomas.forbriger
Browse files

csback2cron does its work now.

This is a legacy commit from before 2015-05-18.
It may be incomplete as well as inconsistent.
See COPYING.legacy and README.history for details.


SVN Path:     http://gpitrsvn.gpi.uni-karlsruhe.de/repos/TFSoftware/trunk
SVN Revision: 4145
SVN UUID:     67feda4a-a26e-11df-9d6e-31afc202ad0c
parent 71a57428
......@@ -46,36 +46,48 @@ version="cscron2back V0.1"
license="GPL"
class Usage(Exception):
class Error(Exception):
def __init__(self, msg):
self.msg = msg
def display(self):
if sys.version_info >= (3,):
print("csback2cron (ERROR): " + self.msg, file=sys.stderr)
else:
print >>sys.stderr, "csback2cron (ERROR): " + self.msg
# -----------------------------------------------------------------------------
class Usage(Error):
# check if constructor is necessary
def __init__(self, msg):
self.msg = msg
def display(self):
usage_text = version + "\nLicense:" + license + "\n" + """
Author: Daniel Armbruster
Usage: csback2cron [-v] [-i CONFIGFILE] <CRONTABFILENAME>
or: csback2cron -h
Note: If [-i CONFIGFILE] isn't passed as a argument, csback2cron uses
~/.csbackrc\n"""
Author: Daniel Armbruster
Usage: csback2cron [-v] [-o] [-i CONFIGFILE] <CRONTABFILENAME>
or: csback2cron -h
Note: If [-i CONFIGFILE] isn't passed as a argument, csback2cron uses
~/.csbackrc as default.\n"""
if sys.version_info >= (3,):
print("csback2cron:" + self.msg, file=sys.stderr)
print("csback2cron: " + self.msg, file=sys.stderr)
print(usage_text, file=sys.stderr)
else:
print >>sys.stderr, "csback2cron:" + self.msg
print >>sys.stderr, "csback2cron: " + self.msg
print >>sys.stderr, usage_text
# -----------------------------------------------------------------------------
def help():
help_text = version + "\nLicense:" + license + "\n" + """
Author: Daniel Armbruster
Usage: csback2cron [-v] [-i CONFIGFILE] <CRONTABFILENAME>
or: csback2cron -h
------------------------------------------------------------------------
-v/--verbose Be verbose.
-h/--help Display this help.
-i CONFIGFILE Path to csbackrc - the configuration file of csback.
If this argument wasn't passed csback2cron assumes
~/.csbackrc as default argument.
<CRONTABFILENAME> Outputfilename of the generated crontab.\n"""
Author: Daniel Armbruster
Usage: csback2cron [-v] [-o] [-i CONFIGFILE] <CRONTABFILENAME>
or: csback2cron -h
-------------------------------------------------------------------------------
-v/--verbose Be verbose.
-h/--help Display this help.
-i CONFIGFILE Path to csbackrc - the configuration file of csback.
If this argument wasn't passed csback2cron assumes
~/.csbackrc as default argument.
-o/--overwrite Overwrite already existing crontab.
<CRONTABFILENAME> Outputfilename of the generated crontab.\n"""
print(help_text)
# -----------------------------------------------------------------------------
......@@ -84,89 +96,130 @@ def get_username():
# -----------------------------------------------------------------------------
class Processor():
def __init__(self, configfile, crontabfile):
def __init__(self, configfile, crontabfile, verbose=False):
self.__configfile = str(configfile)
self.__crontabfile = str(crontabfile)
self.__verbose = verbose
self.__sLines = []
# Check once again the reading function
# Note on sheet of paper
def read(self):
configfile = open(self.__configfile)
lines = configfile.readlines()
configfile.close()
# strip comment lines
lines = list(filter((lambda x: x[0] != '#'), lines))
# strip eol
lines = [l.rstrip() for l in lines]
# get mail= line
tmp = str(list(filter((lambda x: x[0:5] == "mail="), lines))[0])
lines.remove(lines.index(tmp))
if len(tmp[5:]) == 0:
self.__sendmail = False
else:
self.__sendmail = True
self.__addresses = tmp[5:]
# collect setting lines
for line in lines:
l = line.split(" ")
d = dict(zip(self.__keylist, l))
self.__sLines.append(d)
try:
if self.__verbose:
print("csback2cron: Reading CONFIGFILE ... ")
configfile = open(self.__configfile)
lines = configfile.readlines()
configfile.close()
# strip comment lines and empty lines
lines = list(filter((lambda x: x[0] != '#' and x.rstrip() != ''), lines))
# strip eol
lines = [l.rstrip() for l in lines]
if len(lines) == 0:
raise Error("CONFIGFILE not readable.")
# get mail= line
tmp = str(list(filter((lambda x: x[0:5] == "mail="), lines))[0])
lines.remove(tmp)
if len(tmp) == 0 or len(tmp[5:]) == 0:
self.__sendmail = False
else:
self.__sendmail = True
self.__addresses = tmp[5:]
# collect setting lines
if len(lines) == 0:
raise Error("No setting lines in CONFIGFILE given.")
for line in lines:
l = line.split(" ")
if not self.__isdir(l[1]):
raise Error(l[1] + " is not a directory.")
if len(l) == 3 and self.__isdir(l[2]):
l.insert(2,'')
d = dict(zip(self.__keylist, l))
self.__sLines.append(d)
except Error as err:
err.display()
return 2
def write(self, outlines):
def write(self):
# header lines
output = ['# This is <'+self.__crontabfile+'>',
'# Generated with csback2cron.',
'# '+datetime.now().strftime("%Y-%m-%d %H:%M:%S")]
output = ['# This is <' + self.__crontabfile + '>\n',
'# Generated with csback2cron.\n',
'# '+datetime.now().strftime("%Y-%m-%d %H:%M:%S")+"\n"]
if self.__verbose:
print("csback2cron: Conversion ... ")
output.extend(self.__convert())
if self.__verbose:
print("csback2cron: Writing " + self.__crontabfile + " ...")
crontabfile = open(self.__crontabfile, 'w')
crontabfile.writelines(output)
crontabfile.close()
def __convert(self):
res = []
for D in self.__sLines:
for line_dict in self.__sLines:
# check flags
flags = {}
if self.__keylist[2] in D:
flags = self__.check_flags(D[self.__keylist[2]])
s = D[self.__keylist[0]] + " "
if self.__keylist[3] in x:
if self.__keylist[2] in line_dict:
flags = self.__chkflags(line_dict[self.__keylist[2]])
s = line_dict[self.__keylist[0]] + " "
if self.__keylist[3] in line_dict:
# backup is desired - use rsync
s += ''
s += "csbackgen"
if flags[self.__flags[3]]:
s += " " + self.__flags[3] + " '" + flags[self.__flags[3]] + "'"
s += " '" + line_dict[self.__keylist[1]] + "'; rsync"
if flags[self.__flags[3]]:
s += " --exclude= '" + flags[self.__flags[3]] + "'"
s += " '" + line_dict[self.__keylist[1]] + "' '" +\
line_dict[self.__keylist[3]] + "'"
# check of integrity is desired
if not flags[self.__flags[2]]:
s += "; csbackchk"
if flags[self.__flags[1]]:
s += " " + __flags[1]
if flags[self.__flags[3]]:
s += " " + self.__flags[3] + " '" + flags[self.__flags[3]] + "'"
s += " '" + line_dict[self.__keylist[3]] + "'"
if flags[self.__flags[0]]:
s += " '" + line_dict[self.__keylist[1]] + "'"
s += "\n"
else:
# test only
s += 'csbackchk' + D[self.__keylist[1]]
if len(flags) != 0:
if __flags[1] in flags and flags[__flags[1]]:
s += " " + __flags[1]
if __flags[3] in flags and flags[__flags[3]]:
s += " " + __flags[3] + " " + flags[__flags[3]]
s += 'csbackchk'
if self.__flags[1] in flags and flags[self.__flags[1]]:
s += " " + self.__flags[1]
if self.__flags[3] in flags and flags[self.__flags[3]]:
s += " " + self.__flags[3] + " '" + flags[self.__flags[3]] + "'"
s += " '" + line_dict[self.__keylist[1]] + "'\n"
res.append(s)
# email report
if self.__sendmail:
# TODO: variable time
s = '0 12 * * * csbackmail ' + self.__addresses
s = "0 12 * * * csbackmail '" + self.__addresses + "'\n"
res.append(s)
return res
def __check_flags(self, flags):
res = dict.fromkeys(__flags, False)
def __chkflags(self, flags):
res = dict.fromkeys(self.__flags, False)
l = flags.split()
for f in __flags[:3]:
if __flags[f] in l:
res[__flags[f]] == True
for f in self.__flags[:3]:
if str(f) in l:
res[f] = True
# handle exclude flag
if __flags[3] in l and l[l.index(__flags(3)+1)] not in __flags:
res[__flags[3]] = l[l.index(__flags(3)+1)]
if self.__flags[3] in l and \
l[l.index(self.__flags[3])+1] not in self.__flags:
res[self.__flags[3]] = l[l.index(self.__flags[3])+1]
return res
def __isdir(self, dir):
if os.path.isdir(str(dir)):
return True
else:
return False
__flags = ['-c', '-t', '-b', '-e']
__keylist = ['cronexpr', 'source', 'flags', 'target']
# REMEMBER: Not applying all tests yet!
#def __check_cronexpr(self, expr):
#def __check_dir(self, dir):
# -----------------------------------------------------------------------------
def main(argv=None):
......@@ -174,17 +227,22 @@ def main(argv=None):
argv = sys.argv
try:
try:
opts, args = getopt.getopt(argv[1:], "hvi:", ["help", "verbose"])
except getopt.error, msg:
raise Usage(msg)
if len(args) == 0:
raise Usage("CRONTABFILENAME not given.")
output = None
input = '/home/' + get_username()+ '/.csbackrc'
opts, args = getopt.getopt(argv[1:], "hovi:", ["help", "overwrite",\
"verbose"])
except getopt.GetoptError as err:
raise Usage(err.msg)
if len(args) == 1:
outputfile = args[0]
else:
raise Usage("Only one CRONTABFILENAME is allowed.")
inputfile = '/home/' + get_username()+ '/.csbackrc'
verbose = False
overwrite = False
for opt, a in opts:
if opt == "-v":
if opt in ("-v", "--verbose"):
verbose = True
elif opt in ("-o", "--overwrite"):
overwrite = True
elif opt in ("-h", "--help"):
help()
sys.exit()
......@@ -192,12 +250,22 @@ def main(argv=None):
input = a
else:
raise Usage("Unhandled option chosen.")
Processor process(input,output)
if len(args) == 0:
raise Usage("CRONTABFILENAME not given.")
if not os.path.isfile(inputfile):
raise Error("Given CONFIGFILE is not a regular file.")
if not overwrite and os.path.isfile(outputfile):
raise Usage(outputfile +\
" already exists. Enable [-o] to overwrite file.")
process = Processor(inputfile, outputfile, verbose)
process.read()
process.write()
except Usage as err:
err.display()
return 2
except Error as err:
err.display()
return 2
# -----------------------------------------------------------------------------
if __name__ == "__main__":
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment