Repository navigation
Expand file tree
/
Copy pathserverSync
More file actions
executable file
·194 lines (160 loc) · 6.83 KB
/
Copy pathserverSync
File metadata and controls
executable file
·194 lines (160 loc) · 6.83 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/usr/local/bin/python3
# Jordan Marchetto
import sys
import configparser
import os
import time
import datetime
import subprocess
import argparse
#example config fields
LOCAL_WORKSPACE = "/local/file/path/workspace/"
REMOTE_WORKSPACE = "/local/file/path/workspace/"
USERNAME = "my_server_username"
PASSWORD = "hunter2"
SERVER = "servername"
LOG_FILE = "/local/file/path/sync_log.txt"
LOG_FILE_VERBOSE = "/local/file/path/sync_log_verbose.txt"
RSYNC_ARGUMENTS = "" #example: "--chown=username:groupname --chmod=u=rw,og=r"
DEFAULT_CONFIG_PATH = os.path.expanduser("~") + "/.config/serverSync.conf" ##CHANGE THIS, IT NEEDS TO BE A HARDCODED FULL PATH
#do the thing
def main():
#check Usage
args = checkUsage()
#parse config
workspaces = parseConfig()
#check for pull/no pull
if args.pull:
if args.filename:
file_full_path = os.path.abspath(args.filename)
filename = args.filename.split("/")[-1]
else:
file_full_path = os.path.abspath("") + "/"
if args.all:
filename = "full workspace"
else:
filename = file_full_path
else:
#get file: /full/local/path/test.html
file_full_path = os.path.abspath(args.filename)
#get filename: test.html
filename = args.filename.split("/")[-1]
#loop through work to see if we're in one
for workspace in workspaces:
#get all of our workspace specific variables
LOCAL_WORKSPACE = workspaces[workspace]['local_workspace']
REMOTE_WORKSPACE = workspaces[workspace]['remote_workspace']
USERNAME = workspaces[workspace]['username']
SERVER = workspaces[workspace]['server']
RSYNC_ARGUMENTS = workspaces[workspace]['rsync_arguments'] if 'rsync_arguments' in workspaces[workspace] else ""
LOG_FILE = workspaces[workspace]['log_file'] if 'log_file' in workspaces[workspace] else False
LOG_FILE_VERBOSE = workspaces[workspace]['log_file_verbose'] if 'log_file_verbose' in workspaces[workspace] else False
#make sure we're in the workspace
if LOCAL_WORKSPACE not in file_full_path:
continue
#get the path from LOCAL_WORKSPACE onwards: test.html (this handles the case of running script from different dir than file)
#so if run from /local: /path/test.html
relative_path = file_full_path.split(LOCAL_WORKSPACE)[1]
#set up remote path: /full/remote/path/test.html
remote_path = REMOTE_WORKSPACE + relative_path
local_file = file_full_path
#build rsync command
if args.pull:
#pulling down one file or current dir
rsync_cmd = "rsync -avzog %s %s@%s:%s %s"%(RSYNC_ARGUMENTS, USERNAME, SERVER, remote_path, local_file)
if args.all:
#syncing up LOCAL and REMOTE workspaces
rsync_cmd = "rsync -avzog %s %s@%s:%s %s"%(RSYNC_ARGUMENTS, USERNAME, SERVER, REMOTE_WORKSPACE, LOCAL_WORKSPACE)
else:
#update rsync remote and local to be version 3.1, we should be able to use the --chown flag below
rsync_cmd = "rsync -avzog %s %s %s@%s:%s"%(RSYNC_ARGUMENTS, local_file, USERNAME, SERVER, remote_path)
#otherwise:
#rsync_cmd = "scp %s %s@%s:%s"%(local_file, USERNAME, SERVER, remote_path)
#run cmd (or not)
if (args.test):
print(rsync_cmd)
else:
response = subprocess.check_output(rsync_cmd, shell=True)
#get a timestamp
ts = time.time()
timestamp = datetime.datetime.fromtimestamp(ts).strftime('%H:%M:%S %Y-%m-%d')
#write to logs
short_output = ""
long_output = ""
if args.pull:
#SHORT OUTPUT
short_output += "\n(%s) [%s] pulled."%(timestamp, filename)
#LONG OUTPUT
long_output += "\n(%s) [%s] pulled: %s to %s"%(timestamp, filename, file_full_path, remote_path)
long_output += "\ncmd: %s"%(rsync_cmd)
else:
#SHORT OUTPUT
short_output += "\n(%s) [%s] deployed."%(timestamp, filename)
#LONG OUTPUT
long_output += "\n(%s) [%s] deployed: %s to %s"%(timestamp, filename, file_full_path, remote_path)
long_output += "\ncmd: %s"%(rsync_cmd)
if LOG_FILE:
log(short_output, LOG_FILE)
if LOG_FILE_VERBOSE:
log(long_output, LOG_FILE_VERBOSE)
'''
#write to log
'''
def log(text, logfile):
#open log file, change 'a' to 'w' if you want to clear the log file on each update
f = open(logfile, 'a')
f.write(text)
f.close()
'''
#read in from config
'''
def parseConfig():
required_fields = ['local_workspace', 'remote_workspace', 'username', 'server']
#parse the config
config = configparser.ConfigParser()
config.read(DEFAULT_CONFIG_PATH)
#build workspaces dict based on the config
workspaces = {}
for workspace in config:
if workspace is "DEFAULT":
continue
#make a new dict and grab all its fields
workspaces[workspace] = {}
for field in config[workspace]:
val = config[workspace][field]
#handle ~ in the path
if "~" in val:
val = val.replace("~", os.path.expanduser("~"))
workspaces[workspace][field] = val
#validate the workspace
valid_workspace = True
for field in required_fields:
if not field in workspaces[workspace]:
valid_workspace = False
#remove invalid ones
if not valid_workspace:
print("Invalid workspace: " + workspace)
workspaces.pop(workspace)
return workspaces
'''
#make sure CLI call is right
'''
def checkUsage():
example_text = "example:\n serverSync filename.html #push single file\n serverSync -p filename.html #pull single file\n serverSync -ap #pull entire remote workspace"
parser = argparse.ArgumentParser(epilog=example_text, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument('-p', '--pull', action='store_true', help='pull down this directory from remote workspace')
parser.add_argument('-a', '--all', action='store_true', help='pull down entire remote workspace, must be used with -p')
parser.add_argument('-t', '--test', action='store_true', help='only print rsync command, does not run command')
parser.add_argument('filename', nargs='?', help='file to upload, required unless using -p')
args = parser.parse_args()
#make sure we're using -p with -a
if not args.pull and args.all:
parser.print_help()
sys.exit()
#make sure we have either a filename, or we're pulling
if not args.filename and not args.pull:
parser.print_help()
sys.exit()
return args
if __name__ == "__main__":
main()