-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuploader.py
150 lines (130 loc) · 5.2 KB
/
uploader.py
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
# coding: utf-8
import argparse
import subprocess
import logging
import sys
from pathlib import Path, PurePath
import xml.etree.cElementTree as et
from paramiko.client import SSHClient
from paramiko.ssh_exception import BadHostKeyException, SSHException
from yaml import load, Loader
def check_server_up(address):
logging.info("Issuing ping to %s", address)
proc = subprocess.run(["ping", "-c", '2', address], check=True)
return proc.returncode == 0
def upload_files(directory, remote_dir, config):
username = config["username"]
host = config["host"]
port = config["port"] or 22
private_key = str(config["key_path"]) + "/id_rsa"
private_key_pass = config["key_pass"]
logging.info("Uploading to %s", remote_dir)
try:
client = SSHClient()
client.load_system_host_keys()
client.connect(host, port=port, username=username,
key_filename=private_key, passphrase=private_key_pass)
sftp = client.open_sftp()
# Check if the folder exists. If not, create it
try:
sftp.listdir(remote_dir)
except IOError:
sftp.mkdir(remote_dir)
sftp.chdir(remote_dir)
try:
for file in directory:
logging.info("Uploading %s", file)
# The remotepath should contain the file name.
# If the forward slash is omitted, it becomes e.g. AAutomationTestsadtrombone.wav
sftp.put(localpath=file, remotepath=remote_dir + '/' + file, confirm=True)
logging.info("All files uploaded")
except FileNotFoundError as err:
logging.error(err)
client.close()
except BlockingIOError:
logging.error("Can't reach the server. Check that you have the right SSH port")
except BadHostKeyException:
logging.error("Bad Host Key. Check that the SSH key matches the server")
except SSHException as ssh_error:
logging.error(ssh_error)
def get_resource_paths(file):
paths = []
tree = et.parse(file)
root = tree.getroot()
for element in root.iter("chain"):
for prop in element.iter("property"):
# The resource attribute is what contains the path to the file
if prop.attrib['name'] == 'resource':
paths.append(prop.text)
# prevent duplicates
return list(set(paths))
def clean_paths(file, res_paths):
cleaned_file = file.replace('.mlt', '_fixed.mlt')
cleaned_paths = []
tree = et.parse(file)
root = tree.getroot()
for element in root.iter("chain"):
for prop in element.iter("property"):
if prop.attrib['name'] == 'resource' and prop.text in res_paths:
cleaned = prop.text[(prop.text.rindex('/'))+1:]
cleaned_paths.append(cleaned)
prop.text = cleaned
# Save to a new file with all paths adjusted to be relative to the project
tree.write(cleaned_file)
cleaned_paths.append(str(Path(cleaned_file).name))
return cleaned_paths
def get_resource_files(file):
res_paths = get_resource_paths(file)
for path in res_paths:
if path.startswith("/") is False:
# accounting for relative paths
file_path = PurePath(file.replace(str(PurePath(file).name), '') + "/" + path)
else:
# Account for WSL. There is probably a better way to do this
file_path = PurePath(path.replace('C:', '/mnt/c').replace('D:', '/mnt/d'))
logging.info(file_path)
subprocess.run(["cp", "-r", file_path, "."], check=True)
return clean_paths(file, res_paths)
def get_config():
try:
with open("config.yml") as file:
return load(file, Loader=Loader)
except FileNotFoundError:
logging.error("config.yml not found! Check that the file exists and is named correctly!")
subprocess.run(["ls"], check=True)
sys.exit(-1)
def loop_server(host):
attempts = 0
is_up = False
while attempts < 5:
is_up = check_server_up(host)
if is_up is True:
break
logging.info("Attempt %i failed", attempts+1)
attempts += 1
return is_up
def remove_temporary_files(files):
logging.info("Cleaning up %i temporary files", len(files))
for file in files:
subprocess.run(["rm", file], check=True)
def main():
parser = argparse.ArgumentParser(description="Upload files")
parser.add_argument("file", type=str, help="The path to the MLT file")
parser.add_argument("upload_dir", type=str,
help="Where to upload it to, relative to the user's home directory")
args = parser.parse_args()
mlt_file = args.file
remote_dir = args.upload_dir
logging.basicConfig(level=logging.DEBUG)
config = get_config()
host = config["host"]
if loop_server(host) is True:
logging.info("Server is up, we shall proceed")
files = set(get_resource_files(mlt_file))
subprocess.run(["cp", mlt_file.replace(".mlt", "_fixed.mlt"), "."], check=True)
logging.info("Files: %s", files)
upload_files(files, str("/home/" + config["username"] + "/" + remote_dir), config)
remove_temporary_files(files)
else:
logging.warning("The server is not up yet!")
main()