18 import re |
18 import re |
19 import gettext |
19 import gettext |
20 import datetime |
20 import datetime |
21 import subprocess |
21 import subprocess |
22 import shlex |
22 import shlex |
|
23 import locale |
23 import logging |
24 import logging |
|
25 |
|
26 DATADIR = os.path.join(sys.prefix, 'share') |
|
27 |
|
28 |
|
29 def set_utf8_locale(): |
|
30 """Make sure we read/write all text files in UTF-8""" |
|
31 lang, encoding = locale.getlocale() |
|
32 if encoding != 'UTF-8': |
|
33 locale.setlocale(locale.LC_CTYPE, (lang, 'UTF-8')) |
24 |
34 |
25 # Set up Internationalization using gettext |
35 # Set up Internationalization using gettext |
26 # searching for installed locales on /usr/share; uses relative folder if not |
36 # searching for installed locales on /usr/share; uses relative folder if not |
27 # found (windows) |
37 # found (windows) |
28 def install_locale(domain): |
38 def install_locale(domain): |
29 if os.path.exists('/usr/share/pronterface/locale'): |
39 shared_locale_dir = os.path.join(DATADIR, 'locale') |
30 gettext.install(domain, '/usr/share/pronterface/locale', unicode = 1) |
40 if os.path.exists(shared_locale_dir): |
31 elif os.path.exists('/usr/local/share/pronterface/locale'): |
41 gettext.install(domain, shared_locale_dir) |
32 gettext.install(domain, '/usr/local/share/pronterface/locale', |
42 else: |
33 unicode = 1) |
43 gettext.install(domain, './locale') |
34 else: |
|
35 gettext.install(domain, './locale', unicode = 1) |
|
36 |
44 |
37 class LogFormatter(logging.Formatter): |
45 class LogFormatter(logging.Formatter): |
38 def __init__(self, format_default, format_info): |
46 def __init__(self, format_default, format_info): |
39 super(LogFormatter, self).__init__(format_info) |
47 super(LogFormatter, self).__init__(format_info) |
40 self.format_default = format_default |
48 self.format_default = format_default |
69 return sys.executable |
77 return sys.executable |
70 else: |
78 else: |
71 return pixmapfile(filename) |
79 return pixmapfile(filename) |
72 |
80 |
73 def imagefile(filename): |
81 def imagefile(filename): |
74 for prefix in ['/usr/local/share/pronterface/images', |
82 shared_pronterface_images_dir = os.path.join(DATADIR, 'pronterface/images') |
75 '/usr/share/pronterface/images']: |
83 candidate = os.path.join(shared_pronterface_images_dir, filename) |
76 candidate = os.path.join(prefix, filename) |
84 if os.path.exists(candidate): |
77 if os.path.exists(candidate): |
85 return candidate |
78 return candidate |
|
79 local_candidate = os.path.join(os.path.dirname(sys.argv[0]), |
86 local_candidate = os.path.join(os.path.dirname(sys.argv[0]), |
80 "images", filename) |
87 "images", filename) |
81 if os.path.exists(local_candidate): |
88 if os.path.exists(local_candidate): |
82 return local_candidate |
89 return local_candidate |
|
90 frozen_candidate=os.path.join(getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__))),"images",filename) |
|
91 if os.path.exists(frozen_candidate): |
|
92 return frozen_candidate |
83 else: |
93 else: |
84 return os.path.join("images", filename) |
94 return os.path.join("images", filename) |
85 |
95 |
86 def lookup_file(filename, prefixes): |
96 def lookup_file(filename, prefixes): |
87 local_candidate = os.path.join(os.path.dirname(sys.argv[0]), filename) |
97 local_candidate = os.path.join(os.path.dirname(sys.argv[0]), filename) |
88 if os.path.exists(local_candidate): |
98 if os.path.exists(local_candidate): |
89 return local_candidate |
99 return local_candidate |
|
100 if getattr(sys,"frozen",False): prefixes+=[getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__))),] |
90 for prefix in prefixes: |
101 for prefix in prefixes: |
91 candidate = os.path.join(prefix, filename) |
102 candidate = os.path.join(prefix, filename) |
92 if os.path.exists(candidate): |
103 if os.path.exists(candidate): |
93 return candidate |
104 return candidate |
94 return filename |
105 return filename |
95 |
106 |
96 def pixmapfile(filename): |
107 def pixmapfile(filename): |
97 return lookup_file(filename, ['/usr/local/share/pixmaps', |
108 shared_pixmaps_dir = os.path.join(DATADIR, 'pixmaps') |
98 '/usr/share/pixmaps']) |
109 return lookup_file(filename, [shared_pixmaps_dir]) |
99 |
110 |
100 def sharedfile(filename): |
111 def sharedfile(filename): |
101 return lookup_file(filename, ['/usr/local/share/pronterface', |
112 shared_pronterface_dir = os.path.join(DATADIR, 'pronterface') |
102 '/usr/share/pronterface']) |
113 return lookup_file(filename, [shared_pronterface_dir]) |
103 |
114 |
104 def configfile(filename): |
115 def configfile(filename): |
105 return lookup_file(filename, [os.path.expanduser("~/.printrun/"), ]) |
116 return lookup_file(filename, [os.path.expanduser("~/.printrun/"), ]) |
106 |
117 |
107 def decode_utf8(s): |
118 def decode_utf8(s): |
116 |
127 |
117 def format_duration(delta): |
128 def format_duration(delta): |
118 return str(datetime.timedelta(seconds = int(delta))) |
129 return str(datetime.timedelta(seconds = int(delta))) |
119 |
130 |
120 def prepare_command(command, replaces = None): |
131 def prepare_command(command, replaces = None): |
121 command = shlex.split(command.replace("\\", "\\\\").encode()) |
132 command = shlex.split(command.replace("\\", "\\\\")) |
122 if replaces: |
133 if replaces: |
123 replaces["$python"] = sys.executable |
134 replaces["$python"] = sys.executable |
124 for pattern, rep in replaces.items(): |
135 for pattern, rep in replaces.items(): |
125 command = [bit.replace(pattern, rep) for bit in command] |
136 command = [bit.replace(pattern, rep) for bit in command] |
126 command = [bit.encode() for bit in command] |
|
127 return command |
137 return command |
128 |
138 |
129 def run_command(command, replaces = None, stdout = subprocess.STDOUT, stderr = subprocess.STDOUT, blocking = False): |
139 def run_command(command, replaces = None, stdout = subprocess.STDOUT, stderr = subprocess.STDOUT, blocking = False, universal_newlines = False): |
130 command = prepare_command(command, replaces) |
140 command = prepare_command(command, replaces) |
131 if blocking: |
141 if blocking: |
132 return subprocess.call(command) |
142 return subprocess.call(command, universal_newlines = universal_newlines) |
133 else: |
143 else: |
134 return subprocess.Popen(command, stderr = stderr, stdout = stdout) |
144 return subprocess.Popen(command, stderr = stderr, stdout = stdout, universal_newlines = universal_newlines) |
135 |
145 |
136 def get_command_output(command, replaces): |
146 def get_command_output(command, replaces): |
137 p = run_command(command, replaces, |
147 p = run_command(command, replaces, |
138 stdout = subprocess.PIPE, stderr = subprocess.STDOUT, |
148 stdout = subprocess.PIPE, stderr = subprocess.STDOUT, |
139 blocking = False) |
149 blocking = False, universal_newlines = True) |
140 return p.stdout.read() |
150 return p.stdout.read() |
141 |
151 |
142 def dosify(name): |
152 def dosify(name): |
143 return os.path.split(name)[1].split(".")[0][:8] + ".g" |
153 return os.path.split(name)[1].split(".")[0][:8] + ".g" |
144 |
154 |
145 class RemainingTimeEstimator(object): |
155 class RemainingTimeEstimator: |
146 |
156 |
147 drift = None |
157 drift = None |
148 gcode = None |
158 gcode = None |
149 |
159 |
150 def __init__(self, gcode): |
160 def __init__(self, gcode): |
189 # "XXXxYYY+xxx-yyy" |
199 # "XXXxYYY+xxx-yyy" |
190 # "XXX,YYY,ZZZ+xxx+yyy-zzz" |
200 # "XXX,YYY,ZZZ+xxx+yyy-zzz" |
191 # etc |
201 # etc |
192 bdl = re.findall("([-+]?[0-9]*\.?[0-9]*)", bdim) |
202 bdl = re.findall("([-+]?[0-9]*\.?[0-9]*)", bdim) |
193 defaults = [200, 200, 100, 0, 0, 0, 0, 0, 0] |
203 defaults = [200, 200, 100, 0, 0, 0, 0, 0, 0] |
194 bdl = filter(None, bdl) |
204 bdl = [b for b in bdl if b] |
195 bdl_float = [float(value) if value else defaults[i] for i, value in enumerate(bdl)] |
205 bdl_float = [float(value) if value else defaults[i] for i, value in enumerate(bdl)] |
196 if len(bdl_float) < len(defaults): |
206 if len(bdl_float) < len(defaults): |
197 bdl_float += [defaults[i] for i in range(len(bdl_float), len(defaults))] |
207 bdl_float += [defaults[i] for i in range(len(bdl_float), len(defaults))] |
198 for i in range(3): # Check for nonpositive dimensions for build volume |
208 for i in range(3): # Check for nonpositive dimensions for build volume |
199 if bdl_float[i] <= 0: bdl_float[i] = 1 |
209 if bdl_float[i] <= 0: bdl_float[i] = 1 |
203 return build_dimensions[6:9] if len(build_dimensions) >= 9 else None |
213 return build_dimensions[6:9] if len(build_dimensions) >= 9 else None |
204 |
214 |
205 def hexcolor_to_float(color, components): |
215 def hexcolor_to_float(color, components): |
206 color = color[1:] |
216 color = color[1:] |
207 numel = len(color) |
217 numel = len(color) |
208 ndigits = numel / components |
218 ndigits = numel // components |
209 div = 16 ** ndigits - 1 |
219 div = 16 ** ndigits - 1 |
210 return tuple(round(float(int(color[i:i + ndigits], 16)) / div, 2) |
220 return tuple(round(float(int(color[i:i + ndigits], 16)) / div, 2) |
211 for i in range(0, numel, ndigits)) |
221 for i in range(0, numel, ndigits)) |
212 |
222 |
213 def check_rgb_color(color): |
223 def check_rgb_color(color): |
224 |
234 |
225 tempreport_exp = re.compile("([TB]\d*):([-+]?\d*\.?\d*)(?: ?\/)?([-+]?\d*\.?\d*)") |
235 tempreport_exp = re.compile("([TB]\d*):([-+]?\d*\.?\d*)(?: ?\/)?([-+]?\d*\.?\d*)") |
226 def parse_temperature_report(report): |
236 def parse_temperature_report(report): |
227 matches = tempreport_exp.findall(report) |
237 matches = tempreport_exp.findall(report) |
228 return dict((m[0], (m[1], m[2])) for m in matches) |
238 return dict((m[0], (m[1], m[2])) for m in matches) |
|
239 |
|
240 def compile_file(filename): |
|
241 with open(filename) as f: |
|
242 return compile(f.read(), filename, 'exec') |
|
243 |
|
244 def read_history_from(filename): |
|
245 history=[] |
|
246 if os.path.exists(filename): |
|
247 _hf=open(filename,encoding="utf-8") |
|
248 for i in _hf: |
|
249 history.append(i.rstrip()) |
|
250 return history |
|
251 |
|
252 def write_history_to(filename, hist): |
|
253 _hf=open(filename,"w",encoding="utf-8") |
|
254 for i in hist: |
|
255 _hf.write(i+"\n") |
|
256 _hf.close() |