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
113
114
115
116
117
118
119
120
121
|
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 (or default)\n{0} @tabname – synchronizes every entry found in tabname\n{0} -s [@tabname][ entry1[ entry2[ …]]] – synchronizes in server mode (ie don't refresh timestamp)\n\nIf tabname is omitted, will use default file located at ~/.autoSync.tab".format(os.path.basename(sys.argv[0])))
return
firstArg = args.popleft()
if firstArg == "-s":
server = True
firstArg = args.popleft()
tabname = ""
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((lambda i: ["(default)", i][len(i)>0])(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))
return
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))
return
else:
tabname = firstArg.lstrip("@")
else:
args.appendleft(firstArg)
for name, src, dst in getTab(tabname, args):
srcT, dstT = getTimestamp(src, dst)
ignoreFile = os.path.join(src, ".ignore.lst")
if not os.path.exists(ignoreFile):
ignoreFile = None
if tabname == "":
tabname = "(default)"
if srcT >= dstT:
msg("[{} @ {}] sending data to destination".format(name, tabname))
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, tabname))
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")
|