diff options
Diffstat (limited to 'autosync')
| -rw-r--r-- | autosync/__init__.py | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/autosync/__init__.py b/autosync/__init__.py new file mode 100644 index 0000000..458a1f0 --- /dev/null +++ b/autosync/__init__.py @@ -0,0 +1,112 @@ +import glob +import os +import subprocess +import sys +import time + +from collections import deque + +server = False + +def msg(data): + print("\n\033[1;34m:: \033[1;37m{}\033[0m".format(data)) + +def sync(source, dest, ignoreFile=None, verbose=False): + """Synchronizes data between a source and a target.""" + args = ["rsync", "--delete", "-zHaAXS", source, dest] + if ignoreFile is not None: + args.append("--exclude-from="+ignoreFile) + if verbose: + args[2] += "v" + + return subprocess.call(args) + +def getTab(name="", elements=[]): + """Get entries""" + tabData = {} + if name == "": + tabFile = os.path.join(os.environ["HOME"], ".autoSync.tab") + else: + tabFile = os.path.join(os.environ["HOME"], ".autoSync.{}.tab".format(name)) + + with open(tabFile, "r") as f: + for line in f.readlines(): + name, src, dst = filter(lambda i: len(i) > 0, line.rstrip("\n").split("\t")) + tabData[name] = (os.path.expandvars(os.path.expanduser(src)), os.path.expandvars(os.path.expanduser(dst))) + + if len(elements) < 1: + elements = list(tabData.keys()) + + for itemName in elements: + if itemName in tabData.keys(): + yield (itemName, *tabData[itemName]) + +def getTimestamp(source, dest): + """Get source and destination timestamps""" + sourceTS = os.path.join(source, ".lastsync") + destTS = os.path.join(dest, ".lastsync") + + if sync(sourceTS, "/tmp/source.ts") != 0: + with open("/tmp/source.ts", "w") as f: + f.write("0") + if sync(destTS, "/tmp/dest.ts") != 0: + with open("/tmp/dest.ts", "w") as f: + f.write("0") + + with open("/tmp/source.ts", "r") as sourceF, open("/tmp/dest.ts", "r") as destF: + return (float(sourceF.read()), float(destF.read())) + +def run(): + global server + args = deque(sys.argv[1:]) + if len(args) < 1: + print("{0} @ – list available tab names\n{0} @@tabname – list available entries under tabname\n{0} @tabname entry1 entry2 – synchronizes entry1 and entry2 from tabname\n{0} @tabname – synchronizes every entry found in tabname\n{0} -s @[tabname][ entry1[ entry2[ …]]] – synchronizes in server mode (ie don't refresh timestamp)".format(os.path.basename(sys.argv[0]))) + return + + firstArg = args.popleft() + if firstArg == "-s": + server = True + firstArg = args.popleft() + + if firstArg.startswith("@"): + if firstArg.startswith("@@"): # list available entries for tabfile + elts = list(getTab(name=firstArg.lstrip("@"))) + + maxLenName = max(len(line[0]) for line in elts) + maxLenSrc = max(len(line[1]) for line in elts) + maxLenDst = max(len(line[1]) for line in elts) + + msg("Available entries for tabfile {}:".format(firstArg.lstrip("@"))) + print("\n\033[1;37m%-*s %-*s %-*s\033[0m" % (maxLenName, "Name", maxLenSrc, "Source", maxLenDst, "Target")) + for ename, esrc, edst in elts: + print("%-*s %-*s %-*s" % (maxLenName, ename, maxLenSrc, esrc, maxLenDst, edst)) + + elif firstArg == "@": # lists all available tabFiles + files = glob.glob(os.path.join(os.environ["HOME"], ".autoSync.*.tab")) + msg("Available tables:") + print("\n".join("– " + os.path.basename(fileName).split(".", 2)[2][:-4] for fileName in files)) + + else: + firstArg = firstArg.lstrip("@") + for name, src, dst in getTab(firstArg, args): + srcT, dstT = getTimestamp(src, dst) + ignoreFile = os.path.join(src, ".ignore.lst") + if not os.path.exists(ignoreFile): + ignoreFile = None + if srcT >= dstT: + msg("[{} @ {}] sending data to destination".format(name, firstArg)) + if not server: + with open(os.path.join(src, ".lastsync"), "w") as f: + f.write(str(time.time())) + sync(src, dst, ignoreFile, True) + else: + msg("[{} @ {}] gathering data from destination".format(name, firstArg)) + sync(dst, src, ignoreFile, True) + if not server: + with open(os.path.join(src, ".lastsync"), "w") as f: + f.write(str(time.time())) + + if os.path.exists("/tmp/source.ts"): + os.unlink("/tmp/source.ts") + if os.path.exists("/tmp/dest.ts"): + os.unlink("/tmp/dest.ts") |
