printrun-src/printrun/utils.py

changeset 46
cce0af6351f0
parent 15
0bbb006204fc
equal deleted inserted replaced
45:c82943fb205f 46:cce0af6351f0
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()

mercurial