aboutsummaryrefslogtreecommitdiff
path: root/autosync/__init__.py
blob: 458a1f0cd552e00bd710365cb8042949d02987a2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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")