Skip to content
Newer
Older
100644 439 lines (388 sloc) 20 KB
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
1 #!/usr/bin/python
2 # File name: compress-strokes_standalone.py
3 from __future__ import with_statement
4 import os
5 import math
6 import glob
7 import re
8
9 BIG_BYTE_PLUS_ONE = 1 << 8
10
11 def stroke_to_list(stroke, very_slow=False, parsed_to_int=False, strip_minus=True):
12 ## stroke = stroke.replace("'x':", "(x`").replace("'x':", "(x`").replace("'x':", "(x`").replace("'x':", "(x`")
13 ## stroke = stroke.replace(",'", "|'")
14 ## stroke = stroke.replace("'x':", '').replace("'y':", '').replace("'t':", '')
15 if strip_minus: stroke = stroke.replace('-', '') # because minus signs are bad
16 if very_slow: return eval(stroke)
17 strokes = [cur_stroke[1:-1].split('},{') for cur_stroke in stroke.strip()[2:-2].split('],[')]
18 for stroke in strokes:
19 for point_i in range(len(stroke)):
20 point = stroke[point_i]
21 if point[5] == ',':
22 if point[11] == ',':
23 stroke[point_i] = {'x':point[4:5], 'y':point[10:11], 't':point[16:]}
24 elif point[12] == ',':
25 stroke[point_i] = {'x':point[4:5], 'y':point[10:12], 't':point[17:]}
26 elif point[13] == ',':
27 stroke[point_i] = {'x':point[4:5], 'y':point[10:13], 't':point[18:]}
28 elif point[6] == ',':
29 if point[12] == ',':
30 stroke[point_i] = {'x':point[4:6], 'y':point[11:12], 't':point[17:]}
31 elif point[13] == ',':
32 stroke[point_i] = {'x':point[4:6], 'y':point[11:13], 't':point[18:]}
33 elif point[14] == ',':
34 stroke[point_i] = {'x':point[4:6], 'y':point[11:14], 't':point[19:]}
35 elif point[7] == ',':
36 if point[13] == ',':
37 stroke[point_i] = {'x':point[4:7], 'y':point[12:13], 't':point[18:]}
38 elif point[14] == ',':
39 stroke[point_i] = {'x':point[4:7], 'y':point[12:14], 't':point[19:]}
40 elif point[15] == ',':
41 stroke[point_i] = {'x':point[4:7], 'y':point[12:15], 't':point[20:]}
42 else:
43 print('Slow')
44 stroke[point_i] = point.replace("'x':", '').replace("'y':", '').replace("'t':", '').split(',')
45 point = stroke[point_i]
46 stroke[point_i] = {'x':point[0], 'y':point[1], 't':point[2]}
47 if parsed_to_int:
48 strokes = [[{'x':int(point['x']), 'y':int(point['y']), 't':int(point['t'])} for point in stroke] for stroke in strokes]
49 return strokes
50
51
52 def uint_encode(number, total_bytes=0):
53 rtn = []
54 while number:
55 rtn.append(chr(number % BIG_BYTE_PLUS_ONE))
56 number >>= 8
57 while total_bytes > len(rtn):
58 rtn.append('\x00')
59 return ''.join(reversed(rtn))
60
61
62 def uint_decode(number):
63 rtn = 0
64 for character in number:
65 rtn <<= 8
66 if isinstance(character, int):
67 rtn += character
68 else:
69 rtn += ord(character)
70 return rtn
71
72
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
73 def compress_stroke(stroke, version=2, safe=True):
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
74 # lower bits are xs, upper bits are ys
5d98f79 @JasonGross Fixed bugs in stroke compression. Made it so that there's no error if…
authored Aug 3, 2010
75 original_stroke = stroke
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
76 stroke_list = stroke_to_list(stroke)
77 xs, ys, ts = [], [], []
78 if version >= 1:
79 last_t = 0
80 for stroke_part in stroke_list:
81 xs.append([int(point['x'])+1 for point in stroke_part])
82 ys.append([int(point['y'])+1 for point in stroke_part])
83 if version == 0:
84 ts.append([int(point['t'])+1 for point in stroke_part])
85 else:
86 ts.append([])
87 for point in stroke_part:
5d98f79 @JasonGross Fixed bugs in stroke compression. Made it so that there's no error if…
authored Aug 3, 2010
88 if last_t > int(point['t']): return compress_stroke(original_stroke, version=0, safe=safe)
89 if version >= 2 and last_t == int(point['t']) and last_t > 0: return compress_stroke(original_stroke, version=1, safe=safe)
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
90 ts[-1].append((int(point['t']) - last_t) + 1)
91 last_t = int(point['t'])
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
92
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
93 strokes = {'xs':xs, 'ys':ys, 'ts':ts}
94 mins, maxes = {}, {}
95 bits = {}
96 for key in strokes:
97 maxes[key] = max(map(max, strokes[key]))
98 mins[key] = min(map(min, strokes[key]))
99
100 if maxes[key] < 0:
101 mins[key], maxes[key] = -maxes[key], -mins[key]
102 strokes[key] = [[-s for s in part] for part in strokes[key]]
103
104 if mins[key] <= 0:
105 strokes[key] = [[s - mins[key] + 1 for s in part] for part in strokes[key]]
106 mins[key], maxes[key] = 1, maxes[key] - mins[key] + 1
107
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
108 if version < 2 or key == 'ts':
5d98f79 @JasonGross Fixed bugs in stroke compression. Made it so that there's no error if…
authored Aug 3, 2010
109 bits[key] = int(1 + math.floor(math.log(max((1, maxes[key]))) / math.log(2)))
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
110
111
112 if version >= 2:
113 for key in ('xs', 'ys'):
114 for stroke_i, stroke in enumerate(strokes[key]):
115 last = 0
116 for point_i in range(len(stroke)):
117 last, stroke[point_i] = stroke[point_i], stroke[point_i] - last
118 if point_i != 0:
119 stroke[point_i] = sint_encode_to_uint(stroke[point_i])
120 maxes[key] = max(map(max, strokes[key]))
121 mins[key] = min(map(min, strokes[key]))
5d98f79 @JasonGross Fixed bugs in stroke compression. Made it so that there's no error if…
authored Aug 3, 2010
122 bits[key] = int(1 + math.floor(math.log(max((1, maxes[key]))) / math.log(2)))
123 if bits['xs'] + bits['ys'] <= 8: return compress_stroke(original_stroke, version=1, safe=safe)
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
124
125
126 def default_make_first_line(bits, version, points):
127 if bits['xs'] + bits['ys'] <= 8:
128 first_line = str(version) + '\x00' + chr(bits['xs']) + '\x00' + chr(bits['ys'])
129 elif bits['xs'] <= 8 and bits['ys'] <= 8:
130 first_line = str(version) + '\x00' + chr(bits['xs']) + '\x00' + chr(bits['ys'])
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
131 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
132 if bits['xs'] <= 8:
133 first_line = str(version) + '\x00' + chr(bits['xs'])
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
134 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
135 if bits['xs'] < BIG_BYTE_PLUS_ONE:
136 first_line = str(version) + '\x00u' + chr(bits['xs'])
137 else:
138 first_line = str(version) + '\x00ul' + str(bits['xs'])
139
140 if bits['ys'] <= 8:
141 first_line += '\x00' + chr(bits['ys'])
142 else:
143 if bits['ys'] < BIG_BYTE_PLUS_ONE:
144 first_line += '\x00u' + chr(bits['ys'])
145 else:
146 first_line += '\x00ul' + str(bits['ys'])
147 if bits['ts'] <= 8:
148 first_line += '\x00' + chr(bits['ts'])
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
149 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
150 if bits['ts'] < BIG_BYTE_PLUS_ONE:
151 first_line += '\x00u' + chr(bits['ts'])
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
152 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
153 first_line += '\x00ul' + str(bits['ts'])
154 first_line += '\x00'
155 return first_line
156
157 def empty_make_first_line(*args, **kargs):
158 return ''
159
160 def make_encode_point_by_scheme(bits):
161 if bits['xs'] + bits['ys'] <= 8:
162 if bits['ts'] <= 8:
163 def encode_point_by_scheme(point):
164 return chr(point[0] + (point[1] << bits['xs'])) + chr(point[2])
165 else:
166 total_bytes = int(1 + (bits['ts'] - 1) / 8)
167 def encode_point_by_scheme(point):
168 return chr(point[0] + (point[1] << bits['xs'])) + uint_encode(point[2], total_bytes=total_bytes)
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
169 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
170 if bits['xs'] <= 8:
171 if bits['ys'] <= 8:
172 if bits['ts'] <= 8:
173 def encode_point_by_scheme(point):
174 return chr(point[0]) + chr(point[1]) + chr(point[2])
175 else:
176 total_bytes = int(1 + (bits['ts'] - 1) / 8)
177 def encode_point_by_scheme(point):
178 return chr(point[0]) + chr(point[1]) + uint_encode(point[2], total_bytes=total_bytes)
179 else:
180 total_bytes_ys = int(1 + (bits['ys'] - 1) / 8)
181 if bits['ts'] <= 8:
182 def encode_point_by_scheme(point):
183 return chr(point[0]) + uint_encode(point[1], total_bytes=total_bytes_ys) + chr(point[2])
184 else:
185 total_bytes_ts = int(1 + (bits['ts'] - 1) / 8)
186 def encode_point_by_scheme(point):
187 return chr(point[0]) + uint_encode(point[1], total_bytes=total_bytes_ys) + uint_encode(point[2], total_bytes=total_bytes_ts)
188 else:
189 total_bytes_xs = int(1 + (bits['xs'] - 1) / 8)
190 if bits['ys'] <= 8:
191 if bits['ts'] <= 8:
192 def encode_point_by_scheme(point):
193 return uint_encode(point[0], total_bytes=total_bytes_xs) + chr(point[1]) + chr(point[2])
194 else:
195 total_bytes = int(1 + (bits['ts'] - 1) / 8)
196 def encode_point_by_scheme(point):
197 return uint_encode(point[0], total_bytes=total_bytes_xs) + chr(point[1]) + uint_encode(point[2], total_bytes=total_bytes)
198 else:
199 total_bytes_ys = int(1 + (bits['ys'] - 1) / 8)
200 if bits['ts'] <= 8:
201 def encode_point_by_scheme(point):
202 return uint_encode(point[0], total_bytes=total_bytes_xs) + uint_encode(point[1], total_bytes=total_bytes_ys) + chr(point[2])
203 else:
204 total_bytes_ts = int(1 + (bits['ts'] - 1) / 8)
205 def encode_point_by_scheme(point):
206 return uint_encode(point[0], total_bytes=total_bytes_xs) + uint_encode(point[1], total_bytes=total_bytes_ys) + uint_encode(point[2], total_bytes=total_bytes_ts)
207 return encode_point_by_scheme
208
209 def encode_stroke_part(bits, version, points, make_first_line=default_make_first_line):
210 encode_point_by_scheme = make_encode_point_by_scheme(bits)
211 first_line = make_first_line(bits=bits, version=version, points=points)
212 points = [encode_point_by_scheme(point) for point in points]
213 return first_line + ''.join(points)
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
214
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
215
216 if version < 2:
217 points = []
218 for stroke_i in range(len(stroke_list)):
219 points += [(strokes['xs'][stroke_i][point_i], strokes['ys'][stroke_i][point_i], strokes['ts'][stroke_i][point_i])
220 for point_i in range(len(stroke_list[stroke_i]))]
221 points.append((0, 0, 0))
222 points = points[:-1]
223
224 return encode_stroke_part(bits, version, points)
225 else:
226 first_line = default_make_first_line(bits=bits, version=version, points=[(xs[0], ys[0], ts[0]) for xs, ys, ts in \
227 zip(strokes['xs'], strokes['ys'], strokes['ts'])])
228 rtn = [first_line]
229 stroke_parts = [{'xs':xs, 'ys':ys, 'ts':ts} for xs, ys, ts in zip(strokes['xs'], strokes['ys'], strokes['ts'])]
230 default_encode_point_by_scheme = make_encode_point_by_scheme(bits)
231 encoded_zeros = default_encode_point_by_scheme((0, 0, 0))
232 for stroke_i, stroke in enumerate(stroke_parts):
233 first, rest = dict((key, stroke[key][0]) for key in stroke), dict((key, stroke[key][1:]) for key in stroke)
234 if rest['xs']: # not a single point
235 stroke_bits = {'ts':bits['ts']}
236 stroke_maxes = {}
237 for key in ('xs', 'ys'):
238 stroke_maxes[key] = max(rest[key])
5d98f79 @JasonGross Fixed bugs in stroke compression. Made it so that there's no error if…
authored Aug 3, 2010
239 stroke_bits[key] = int(1 + math.floor(math.log(max((1, maxes[key]))) / math.log(2)))
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
240 if rest['xs'] and stroke_bits['xs'] + stroke_bits['ys'] <= 8:
241 rtn.append(default_encode_point_by_scheme((stroke_bits['xs'], stroke_bits['ys'], 0)))
242 rtn.append(default_encode_point_by_scheme((first['xs'], first['ys'], first['ts'])))
243 rtn.append(encode_stroke_part(stroke_bits, version, zip(rest['xs'], rest['ys'], rest['ts']), make_first_line=empty_make_first_line))
244 rtn.append(encode_stroke_part(stroke_bits, version, [(0,0,0)], make_first_line=empty_make_first_line))
245 else:
246 rtn.append(encode_stroke_part(bits, version, zip(stroke['xs'], stroke['ys'], stroke['ts']), make_first_line=empty_make_first_line))
247 rtn.append(encoded_zeros)
248 rtn = ''.join(rtn[:-1])
249 return rtn
250
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
251
252
253 def decompress_stroke(cstroke, to_string=True, point_to_string=False):
254 # lower bits are xs, upper bits are ys
255 ## print(cstroke)
256 if isinstance(cstroke, str): cstroke = map(ord, cstroke)
257 else: cstroke = list(cstroke)
258 version = int(''.join(map(chr, cstroke[:cstroke.index(0)])))
259 cstroke = cstroke[cstroke.index(0)+1:]
260 bits = {}
261 for key in ('xs', 'ys', 'ts'):
262 if cstroke[0] != ord('u') or (cstroke[1] == 0 and cstroke[2] != 0):
263 bits[key] = cstroke[0]
264 cstroke = cstroke[2:]
265 elif cstroke[0] == ord('u'):
266 if cstroke[1] != ord('l') or (cstroke[2] == 0 and cstroke[3] != 0):
267 bits[key] = cstroke[1]
268 cstroke = cstroke[3:]
269 elif cstroke[1] == ord('l'):
270 bits[key] = int(cstroke[2:cstroke.index(0)])
271 cstroke = cstroke[cstroke.index(0)+1:]
272 else:
273 raise ValueError('cstroke must have l for key ' + key) # todo: make this less cryptic
274 else:
275 raise ValueError('cstroke must have u for key ' + key) # todo: make this less cryptic
276
277 stroke = []
278
279 x_bytes = int(1 + (bits['xs'] - 1) / 8)
280 y_bytes = int(1 + (bits['ys'] - 1) / 8)
281 t_bytes = int(1 + (bits['ts'] - 1) / 8)
282 ## print(bits)
283
284 while cstroke:
285 point = {}
286 if bits['xs'] + bits['ys'] <= 8:
287 xs_and_ys = cstroke[0]
288 cstroke = cstroke[1:]
289 point['xs'], point['ys'] = (xs_and_ys % (1 << bits['xs'])), (xs_and_ys >> bits['xs'])
290 else:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
291 point['xs'] = uint_decode(cstroke[:x_bytes])
292 cstroke = cstroke[x_bytes:]
293
294 point['ys'] = uint_decode(cstroke[:y_bytes])
295 cstroke = cstroke[y_bytes:]
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
296
297 point['ts'] = uint_decode(cstroke[:t_bytes])
298 cstroke = cstroke[t_bytes:]
299
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
300 if version >= 2:
301 if point['ts'] == 0:
302 cur_bits = point
303 if cur_bits['xs'] + cur_bits['ys'] > 8:
304 raise ValueError('Per-stroke compression is only implemented for a strokes with points which each fit into a single byte.')
305 cur_bits['ts'] = bits['ts']
306
307 # decode the first point, which goes according to the old scheme
308 point = {}
309 if bits['xs'] + bits['ys'] <= 8:
310 xs_and_ys = cstroke[0]
311 cstroke = cstroke[1:]
312 point['xs'], point['ys'] = (xs_and_ys % (1 << bits['xs'])), (xs_and_ys >> bits['xs'])
313 else:
314 point['xs'] = uint_decode(cstroke[:x_bytes])
315 cstroke = cstroke[x_bytes:]
316
317 point['ys'] = uint_decode(cstroke[:y_bytes])
318 cstroke = cstroke[y_bytes:]
319
320 point['ts'] = uint_decode(cstroke[:t_bytes])
321 cstroke = cstroke[t_bytes:]
322 stroke.append(point)
323 else:
324 cur_bits = bits
325 stroke.append(point)
326
327
328
329 while cstroke and (point['xs'] != 0 or point['ys'] != 0 or point['ts'] != 0): # keep going until we get to (0, 0, 0), where we revert back to the old scheme.
330 point = {}
331
332 if cur_bits['xs'] + cur_bits['ys'] <= 8:
333 xs_and_ys = cstroke[0]
334 cstroke = cstroke[1:]
335 point['xs'], point['ys'] = (xs_and_ys % (1 << cur_bits['xs'])), (xs_and_ys >> cur_bits['xs'])
336 else:
337 point['xs'] = uint_decode(cstroke[:x_bytes])
338 cstroke = cstroke[x_bytes:]
339
340 point['ys'] = uint_decode(cstroke[:y_bytes])
341 cstroke = cstroke[y_bytes:]
342
343 point['ts'] = uint_decode(cstroke[:t_bytes])
344 cstroke = cstroke[t_bytes:]
345 stroke.append(point)
346 else:
347 stroke.append(point)
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
348
349 stroke_list = []
350 cur_stroke = []
351 if version >= 1:
352 last_t = 0
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
353 if version >= 2:
354 last_x = 0
355 last_y = 0
356 is_first_in_stroke_part = True
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
357 for point in stroke:
358 if point['xs'] != 0 or point['ys'] != 0 or point['ts'] != 0:
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
359 cur_t = point['ts'] - 1
360 cur_x = point['xs']
361 cur_y = point['ys']
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
362 if version >= 1:
363 cur_t += last_t
364 last_t = cur_t
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
365 if version >= 2:
366 if not is_first_in_stroke_part:
367 cur_x = last_x + sint_decode_from_uint(cur_x)
368 cur_y = last_y + sint_decode_from_uint(cur_y)
369 last_x = cur_x
370 last_y = cur_y
371 cur_stroke.append({'x':cur_x-1, 'y':cur_y-1, 't':cur_t})
372 is_first_in_stroke_part = False
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
373 else:
374 stroke_list.append(cur_stroke)
375 cur_stroke = []
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
376 is_first_in_stroke_part = True
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
377 if cur_stroke:
378 stroke_list.append(cur_stroke)
379 cur_stroke = []
380 if to_string:
381 return '[' + ','.join('[' + ','.join("{'x':%(x)d,'y':%(y)d,'t':%(t)d}" % point for point in stroke_part) + ']' for stroke_part in stroke_list) + ']'
382 else:
383 if point_to_string:
384 stroke_list = [[{'x':str(point['x']), 'y':str(point['y']), 't':str(point['t'])} for point in stroke] for stroke in stroke_list]
385 return stroke_list
386
387
388
6159b46 @JasonGross Updated stroke compression to version 2. The new algorithm uses diffe…
authored Aug 3, 2010
389 def sint_encode_to_uint(number):
390 if number > 0:
391 return 2 * number - 1
392 else:
393 return -2 * number
394
395
396 def sint_decode_from_uint(number):
397 if number % 2 == 0:
398 return -number / 2
399 else:
400 return (number + 1) / 2
401
402
e33abe6 @JasonGross Initial commit.
authored Aug 3, 2010
403 def compress_all_strokes_in_current_directory(uncompressed_ext='.stroke', compressed_ext='.cstroke', remove_old=True, verbose=True, show_compression=True):
404 for base, dirs, files in os.walk(os.getcwd()):
405 if verbose: print("I'm in " + base)
406 for file_name in files:
407 if file_name[-len(uncompressed_ext):] == uncompressed_ext:
408 if not show_compression: print('Compressing %s...' % file_name)
409 with open(os.path.join(base, file_name), 'rb') as f:
410 stroke = f.read()
411 new_stroke = compress_stroke(stroke)
412 with open(os.path.join(base, file_name.replace(uncompressed_ext, compressed_ext)), 'wb') as f:
413 f.write(new_stroke)
414 if show_compression: print('Compressed %s at\t\t%.2f%%' % (file_name, 100.0 * len(new_stroke) / len(stroke)))
415 if remove_old:
416 os.rename(os.path.join(base, file_name), os.path.join(base, file_name + '.bak'))
417 # Testing to make sure that we can actually decompress the new file correctly before deleting the old file
418 with open(os.path.join(base, file_name + '.bak'), 'rb') as f:
419 old_stroke = f.read()
420 with open(os.path.join(base, file_name.replace(uncompressed_ext, compressed_ext)), 'rb') as f:
421 new_stroke = f.read()
422 new_old_stroke = decompress_stroke(new_stroke)
423 if new_old_stroke.strip() != old_stroke.strip() and stroke_to_list(new_old_stroke) != stroke_to_list(old_stroke):
424 os.rename(os.path.join(base, file_name + '.bak'), os.path.join(base, file_name))
425 os.remove(os.path.join(base, file_name.replace(uncompressed_ext, compressed_ext)))
426 print('Error on stroke %s in %s' % (file_name, base))
427 print('I wanted:')
428 print(stroke_to_list(old_stroke))
429 print('I got:')
430 print(stroke_to_list(new_old_stroke))
431 print('The compressed version is:')
432 print(repr(new_stroke))
433 raw_input('Press enter or ^C')
434 else:
435 os.remove(os.path.join(base, file_name + '.bak'))
436
437
438 if __name__ == '__main__':
439 compress_all_strokes_in_current_directory()
Something went wrong with that request. Please try again.