-
Notifications
You must be signed in to change notification settings - Fork 0
/
duetcfgen.py
executable file
·154 lines (114 loc) · 3.89 KB
/
duetcfgen.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
151
152
153
#!/usr/bin/python3
# Duet config generator, by Andre Ruiz <andre.ruiz @ gmail.com>
# Please contribute at https://github.com/token47/duetcfgen
import sys, os, re, shutil
import tomlkit as toml
import jinja2
import ftptool
root_dir = os.path.dirname(sys.argv[0]) or '.'
build_dir = "build"
backup_dir = "backup"
comment_column = 50
def load_variables(rootdir, filename):
with open(rootdir + '/' + filename, 'r', encoding='utf-8') as f:
variables = toml.parse(f.read())
try:
with open(os.path.expanduser('~/.duetcfgenvars.toml'), 'r', encoding='utf-8') as f:
user_variables = toml.parse(f.read())
return array_merge(variables, user_variables)
except:
pass
return variables
def load_template(rootdir, filename, variables):
j2_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(rootdir),
trim_blocks=True)
return j2_env.get_template(filename).render(variables)
def switch_cfg_file(name):
global outputfd
if outputfd:
outputfd.close()
if name:
create_dir(build_dir + '/' + os.path.dirname(name))
log_normal('generating ' + name)
outputfd = open(build_dir + '/' + name, 'w')
def write_cfg_line(text):
if outputfd:
e = re.fullmatch("(?P<command>[^;]*)?(?P<comment>;.*)?", text)
command = e.group("command") or ''
comment = e.group("comment") or ''
command = command.strip()
comment = comment.strip()
if command:
l = len(command)
if l < comment_column: command += " " * (comment_column - l)
comment = ' ' + comment
outputfd.write(command + comment + '\n')
else:
log_error('Tried to write without opening a file first, check template')
def create_dir(dirname):
os.makedirs(dirname, exist_ok=True)
def initialize_build_dir():
log_normal("Cleaning build dir")
if os.path.isdir(build_dir):
shutil.rmtree(build_dir)
create_dir(build_dir)
def initialize_backup_dir():
log_normal("Cleaning backup dir")
if os.path.isdir(backup_dir):
shutil.rmtree(backup_dir)
create_dir(backup_dir)
def log_error(msg):
print('ERROR: ' + msg)
sys.exit(1)
def log_normal(msg):
print('LOG: ' + msg)
def generate_config():
initialize_build_dir()
for line in rendered.split("\n"):
if re.match("#", line): continue
if re.fullmatch("[ \t]*", line): continue
f = re.fullmatch("@file[ \t]+(?P<file>.*)", line)
if f:
switch_cfg_file(f.group("file"))
continue
write_cfg_line(line)
def array_merge(destination, source):
for key, value in source.items():
if isinstance(value, dict):
node = destination.setdefault(key, {})
array_merge(node, value)
else:
destination[key] = value
return destination
def connect_ftp():
global duet_ftp
log_normal("connecting to the Duet by FTP")
try:
duet_ftp = ftptool.FTPHost.connect(host=variables['net']['ip_address'], user="duet",
password=variables['printer']['password'], debuglevel=0, timeout=10)
except Exception as e:
log_error("Could not connect to duet. Reason: " + str(e))
def disconnect_ftp():
global duet_ftp
duet_ftp.quit()
def upload_by_ftp():
global duet_ftp
log_normal('uploading files to duet, please wait')
duet_ftp.mirror_to_remote(build_dir, "/")
log_normal('uploading finished')
def download_by_ftp():
global duet_ftp
initialize_backup_dir()
log_normal('downloading files from duet, please wait')
duet_ftp.mirror_to_local("/", backup_dir)
log_normal('downloading finished')
variables = load_variables(root_dir, "variables.toml")
rendered = load_template(root_dir, "template.jinja", variables)
outputfd = None
duet_ftp = None
generate_config()
connect_ftp()
download_by_ftp()
upload_by_ftp()
disconnect_ftp()