author | rgbecker |
Mon, 06 Aug 2012 09:21:41 +0000 | |
changeset 3569 | b4bb97f6ed72 |
parent 3517 | d49ec5554d81 |
child 3617 | ae5744e97c42 |
permissions | -rw-r--r-- |
2625
71abbda1f58c
reportlab.lib: break out rltempfile.py to avoid rl_accel imports
rgbecker
parents:
2565
diff
changeset
|
1 |
#Copyright ReportLab Europe Ltd. 2000-2006 |
494 | 2 |
#see license.txt for license details |
2625
71abbda1f58c
reportlab.lib: break out rltempfile.py to avoid rl_accel imports
rgbecker
parents:
2565
diff
changeset
|
3 |
# $URI:$ |
2327
c40a1b477f3f
Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents:
2313
diff
changeset
|
4 |
__version__=''' $Id$ ''' |
3029 | 5 |
__doc__='''Gazillions of miscellaneous internal utility functions''' |
562 | 6 |
|
3134 | 7 |
import os, sys, imp, time |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
8 |
try: |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
9 |
from hashlib import md5 |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
10 |
except: |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
11 |
from md5 import md5 |
2499 | 12 |
from reportlab.lib.logger import warnOnce |
2625
71abbda1f58c
reportlab.lib: break out rltempfile.py to avoid rl_accel imports
rgbecker
parents:
2565
diff
changeset
|
13 |
from rltempfile import get_rl_tempfile, get_rl_tempdir, _rl_getuid |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
14 |
|
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
15 |
def isSeqType(v,_st=(tuple,list)): |
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
16 |
return isinstance(v,_st) |
2499 | 17 |
|
2259 | 18 |
if sys.hexversion<0x2030000: |
19 |
True = 1 |
|
20 |
False = 0 |
|
562 | 21 |
|
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
22 |
if sys.hexversion >= 0x02000000: |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
23 |
def _digester(s): |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
24 |
return md5(s).hexdigest() |
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
25 |
else: |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
26 |
# hexdigest not available in 1.5 |
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
27 |
def _digester(s): |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
28 |
return join(map(lambda x : "%02x" % ord(x), md5(s).digest()), '') |
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
29 |
|
2215 | 30 |
def _findFiles(dirList,ext='.ttf'): |
31 |
from os.path import isfile, isdir, join as path_join |
|
32 |
from os import listdir |
|
33 |
ext = ext.lower() |
|
34 |
R = [] |
|
35 |
A = R.append |
|
36 |
for D in dirList: |
|
37 |
if not isdir(D): continue |
|
38 |
for fn in listdir(D): |
|
39 |
fn = path_join(D,fn) |
|
40 |
if isfile(fn) and (not ext or fn.lower().endswith(ext)): A(fn) |
|
41 |
return R |
|
42 |
||
43 |
try: |
|
44 |
_UserDict = dict |
|
45 |
except: |
|
46 |
from UserDict import UserDict as _UserDict |
|
47 |
||
48 |
class CIDict(_UserDict): |
|
3328 | 49 |
def __init__(self,*args,**kwds): |
50 |
for a in args: self.update(a) |
|
51 |
self.update(kwds) |
|
2215 | 52 |
|
53 |
def update(self,D): |
|
54 |
for k,v in D.items(): self[k] = v |
|
55 |
||
56 |
def __setitem__(self,k,v): |
|
57 |
try: |
|
58 |
k = k.lower() |
|
59 |
except: |
|
60 |
pass |
|
61 |
_UserDict.__setitem__(self,k,v) |
|
62 |
||
63 |
def __getitem__(self,k): |
|
64 |
try: |
|
65 |
k = k.lower() |
|
66 |
except: |
|
67 |
pass |
|
68 |
return _UserDict.__getitem__(self,k) |
|
69 |
||
70 |
def __delitem__(self,k): |
|
71 |
try: |
|
72 |
k = k.lower() |
|
73 |
except: |
|
74 |
pass |
|
75 |
return _UserDict.__delitem__(self,k) |
|
76 |
||
77 |
def get(self,k,dv=None): |
|
78 |
try: |
|
79 |
return self[k] |
|
80 |
except KeyError: |
|
81 |
return dv |
|
82 |
||
3326 | 83 |
def __contains__(self,k): |
2215 | 84 |
try: |
85 |
self[k] |
|
86 |
return True |
|
87 |
except: |
|
88 |
return False |
|
89 |
||
90 |
def pop(self,k,*a): |
|
91 |
try: |
|
92 |
k = k.lower() |
|
93 |
except: |
|
94 |
pass |
|
95 |
return _UserDict.pop(*((self,k)+a)) |
|
96 |
||
97 |
def setdefault(self,k,*a): |
|
98 |
try: |
|
99 |
k = k.lower() |
|
100 |
except: |
|
101 |
pass |
|
102 |
return _UserDict.setdefault(*((self,k)+a)) |
|
1837
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
103 |
|
1902 | 104 |
if os.name == 'mac': |
105 |
#with the Mac, we need to tag the file in a special |
|
106 |
#way so the system knows it is a PDF file. |
|
107 |
#This supplied by Joe Strout |
|
2057
22e7a13fa031
Fixed so that file creator and types are now correctly set on the Mac again
rptlab
parents:
2053
diff
changeset
|
108 |
import macfs, macostools |
2007 | 109 |
_KNOWN_MAC_EXT = { |
110 |
'BMP' : ('ogle','BMP '), |
|
111 |
'EPS' : ('ogle','EPSF'), |
|
112 |
'EPSF': ('ogle','EPSF'), |
|
113 |
'GIF' : ('ogle','GIFf'), |
|
114 |
'JPG' : ('ogle','JPEG'), |
|
115 |
'JPEG': ('ogle','JPEG'), |
|
116 |
'PCT' : ('ttxt','PICT'), |
|
117 |
'PICT': ('ttxt','PICT'), |
|
118 |
'PNG' : ('ogle','PNGf'), |
|
119 |
'PPM' : ('ogle','.PPM'), |
|
120 |
'TIF' : ('ogle','TIFF'), |
|
121 |
'TIFF': ('ogle','TIFF'), |
|
2051
50350756e12c
Added HTML to the Mac markfilename routine - HTML files should now 'know'
johnprecedo
parents:
2045
diff
changeset
|
122 |
'PDF' : ('CARO','PDF '), |
2057
22e7a13fa031
Fixed so that file creator and types are now correctly set on the Mac again
rptlab
parents:
2053
diff
changeset
|
123 |
'HTML': ('MSIE','TEXT'), |
2007 | 124 |
} |
125 |
def markfilename(filename,creatorcode=None,filetype=None,ext='PDF'): |
|
1902 | 126 |
try: |
2007 | 127 |
if creatorcode is None or filetype is None and ext is not None: |
128 |
try: |
|
3134 | 129 |
creatorcode, filetype = _KNOWN_MAC_EXT[ext.upper()] |
2007 | 130 |
except: |
131 |
return |
|
1902 | 132 |
macfs.FSSpec(filename).SetCreatorType(creatorcode,filetype) |
2051
50350756e12c
Added HTML to the Mac markfilename routine - HTML files should now 'know'
johnprecedo
parents:
2045
diff
changeset
|
133 |
macostools.touched(filename) |
1902 | 134 |
except: |
135 |
pass |
|
136 |
else: |
|
137 |
def markfilename(filename,creatorcode=None,filetype=None): |
|
138 |
pass |
|
139 |
||
2244 | 140 |
import reportlab |
2251 | 141 |
__RL_DIR=os.path.dirname(reportlab.__file__) #possibly relative |
142 |
_RL_DIR=os.path.isabs(__RL_DIR) and __RL_DIR or os.path.abspath(__RL_DIR) |
|
2244 | 143 |
del reportlab |
144 |
||
2225 | 145 |
#Attempt to detect if this copy of reportlab is running in a |
146 |
#file system (as opposed to mostly running in a zip or McMillan |
|
147 |
#archive or Jar file). This is used by test cases, so that |
|
148 |
#we can write test cases that don't get activated in a compiled |
|
2244 | 149 |
try: |
150 |
__file__ |
|
151 |
except: |
|
152 |
__file__ = sys.argv[0] |
|
2305 | 153 |
import glob, fnmatch |
2244 | 154 |
try: |
155 |
_isFSD = not __loader__ |
|
2484 | 156 |
_archive = os.path.normcase(os.path.normpath(__loader__.archive)) |
2327
c40a1b477f3f
Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents:
2313
diff
changeset
|
157 |
_archivepfx = _archive + os.sep |
2484 | 158 |
_archivedir = os.path.dirname(_archive) |
2327
c40a1b477f3f
Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents:
2313
diff
changeset
|
159 |
_archivedirpfx = _archivedir + os.sep |
2305 | 160 |
_archivepfxlen = len(_archivepfx) |
161 |
_archivedirpfxlen = len(_archivedirpfx) |
|
2352 | 162 |
def __startswith_rl(fn, |
2484 | 163 |
_archivepfx=_archivepfx, |
164 |
_archivedirpfx=_archivedirpfx, |
|
165 |
_archive=_archive, |
|
166 |
_archivedir=_archivedir, |
|
2352 | 167 |
os_path_normpath=os.path.normpath, |
168 |
os_path_normcase=os.path.normcase, |
|
169 |
os_getcwd=os.getcwd, |
|
170 |
os_sep=os.sep, |
|
171 |
os_sep_len = len(os.sep)): |
|
172 |
'''if the name starts with a known prefix strip it off''' |
|
173 |
fn = os_path_normpath(fn.replace('/',os_sep)) |
|
174 |
nfn = os_path_normcase(fn) |
|
175 |
if nfn in (_archivedir,_archive): return 1,'' |
|
176 |
if nfn.startswith(_archivepfx): return 1,fn[_archivepfxlen:] |
|
177 |
if nfn.startswith(_archivedirpfx): return 1,fn[_archivedirpfxlen:] |
|
178 |
cwd = os_path_normcase(os_getcwd()) |
|
179 |
n = len(cwd) |
|
180 |
if nfn.startswith(cwd): |
|
181 |
if fn[n:].startswith(os_sep): return 1, fn[n+os_sep_len:] |
|
182 |
if n==len(fn): return 1,'' |
|
183 |
return not os.path.isabs(fn),fn |
|
2305 | 184 |
|
185 |
def _startswith_rl(fn): |
|
186 |
return __startswith_rl(fn)[1] |
|
187 |
||
188 |
def rl_glob(pattern,glob=glob.glob,fnmatch=fnmatch.fnmatch, _RL_DIR=_RL_DIR,pjoin=os.path.join): |
|
189 |
c, pfn = __startswith_rl(pattern) |
|
2307 | 190 |
r = glob(pfn) |
2305 | 191 |
if c or r==[]: |
2307 | 192 |
r += map(lambda x,D=_archivepfx,pjoin=pjoin: pjoin(_archivepfx,x),filter(lambda x,pfn=pfn,fnmatch=fnmatch: fnmatch(x,pfn),__loader__._files.keys())) |
2305 | 193 |
return r |
2244 | 194 |
except: |
195 |
_isFSD = os.path.isfile(__file__) #slight risk of wrong path |
|
196 |
__loader__ = None |
|
2305 | 197 |
def _startswith_rl(fn): |
198 |
return fn |
|
199 |
def rl_glob(pattern,glob=glob.glob): |
|
200 |
return glob(pattern) |
|
201 |
del glob, fnmatch |
|
2244 | 202 |
_isFSSD = _isFSD and os.path.isfile(os.path.splitext(__file__)[0] +'.py') |
203 |
||
1837
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
204 |
def isFileSystemDistro(): |
2225 | 205 |
'''return truth if a file system distribution''' |
206 |
return _isFSD |
|
1837
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
207 |
|
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
208 |
def isCompactDistro(): |
2225 | 209 |
'''return truth if not a file system distribution''' |
210 |
return not _isFSD |
|
1837
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
211 |
|
a3920893b1b8
Back in synch, diagnostic function for distro type added
andy_robinson
parents:
1835
diff
changeset
|
212 |
def isSourceDistro(): |
2225 | 213 |
'''return truth if a source file system distribution''' |
214 |
return _isFSSD |
|
1143 | 215 |
|
413 | 216 |
try: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
217 |
#raise ImportError |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
218 |
### NOTE! FP_STR SHOULD PROBABLY ALWAYS DO A PYTHON STR() CONVERSION ON ARGS |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
219 |
### IN CASE THEY ARE "LAZY OBJECTS". ACCELLERATOR DOESN'T DO THIS (YET) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
220 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
221 |
from _rl_accel import fp_str # in case of builtin version |
2053 | 222 |
except ImportError: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
223 |
from reportlab.lib._rl_accel import fp_str # specific |
2053 | 224 |
except ImportError: |
2139 | 225 |
from math import log |
226 |
_log_10 = lambda x,log=log,_log_e_10=log(10.0): log(x)/_log_e_10 |
|
227 |
_fp_fmts = "%.0f", "%.1f", "%.2f", "%.3f", "%.4f", "%.5f", "%.6f" |
|
228 |
import re |
|
229 |
_tz_re = re.compile('0+$') |
|
230 |
del re |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
231 |
def fp_str(*a): |
3134 | 232 |
'''convert separate arguments (or single sequence arg) into space separated numeric strings''' |
2499 | 233 |
if len(a)==1 and isSeqType(a[0]): a = a[0] |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
234 |
s = [] |
2139 | 235 |
A = s.append |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
236 |
for i in a: |
2139 | 237 |
sa =abs(i) |
238 |
if sa<=1e-7: A('0') |
|
239 |
else: |
|
240 |
l = sa<=1 and 6 or min(max(0,(6-int(_log_10(sa)))),6) |
|
241 |
n = _fp_fmts[l]%i |
|
242 |
if l: |
|
243 |
n = _tz_re.sub('',n) |
|
244 |
try: |
|
245 |
if n[-1]=='.': n = n[:-1] |
|
246 |
except: |
|
247 |
print i, n |
|
248 |
raise |
|
249 |
A((n[0]!='0' or len(n)==1) and n or n[1:]) |
|
3134 | 250 |
return ' '.join(s) |
448 | 251 |
|
981 | 252 |
#hack test for comma users |
253 |
if ',' in fp_str(0.25): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
254 |
_FP_STR = fp_str |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
255 |
def fp_str(*a): |
3134 | 256 |
return _FP_STR(*a).replace(',','.') |
981 | 257 |
|
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
258 |
def recursiveImport(modulename, baseDir=None, noCWD=0, debug=0): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
259 |
"""Dynamically imports possible packagized module, or raises ImportError""" |
2160 | 260 |
normalize = lambda x: os.path.normcase(os.path.abspath(os.path.normpath(x))) |
261 |
path = map(normalize,sys.path) |
|
2156 | 262 |
if baseDir: |
2499 | 263 |
if not isSeqType(baseDir): |
2156 | 264 |
tp = [baseDir] |
1833
135322abc191
Fix recursivImport for case when baseDir is a sequence
rgbecker
parents:
1821
diff
changeset
|
265 |
else: |
2156 | 266 |
tp = filter(None,list(baseDir)) |
267 |
for p in tp: |
|
2160 | 268 |
p = normalize(p) |
2156 | 269 |
if p not in path: path.insert(0,p) |
1396
40d1361f08b7
Enhanced the error message from recursiveImport
andy_robinson
parents:
1389
diff
changeset
|
270 |
|
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
271 |
if noCWD: |
2160 | 272 |
for p in ('','.',normalize('.')): |
273 |
while p in path: |
|
274 |
if debug: print 'removed "%s" from path' % p |
|
275 |
path.remove(p) |
|
276 |
elif '.' not in path: |
|
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
277 |
path.insert(0,'.') |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
278 |
|
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
279 |
if debug: |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
280 |
import pprint |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
281 |
pp = pprint.pprint |
2244 | 282 |
print 'path=', |
283 |
pp(path) |
|
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2160
diff
changeset
|
284 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
285 |
#make import errors a bit more informative |
2156 | 286 |
opath = sys.path |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
287 |
try: |
2156 | 288 |
sys.path = path |
2160 | 289 |
exec 'import %s\nm = %s\n' % (modulename,modulename) in locals() |
290 |
sys.path = opath |
|
2156 | 291 |
return m |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
292 |
except ImportError: |
2160 | 293 |
sys.path = opath |
2156 | 294 |
msg = "recursiveimport(%s,baseDir=%s) failed" % (modulename,baseDir) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
295 |
if baseDir: |
3326 | 296 |
msg = msg + " under paths '%s'" % repr(path) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
297 |
raise ImportError, msg |
1396
40d1361f08b7
Enhanced the error message from recursiveImport
andy_robinson
parents:
1389
diff
changeset
|
298 |
|
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
299 |
def recursiveGetAttr(obj, name): |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
300 |
"Can call down into e.g. object1.object2[4].attr" |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
301 |
return eval(name, obj.__dict__) |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
302 |
|
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
303 |
def recursiveSetAttr(obj, name, value): |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
304 |
"Can call down into e.g. object1.object2[4].attr = value" |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
305 |
#get the thing above last. |
3134 | 306 |
tokens = name.split('.') |
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
307 |
if len(tokens) == 1: |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
308 |
setattr(obj, name, value) |
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2160
diff
changeset
|
309 |
else: |
3134 | 310 |
most = '.'.join(tokens[:-1]) |
1821
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
311 |
last = tokens[-1] |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
312 |
parent = recursiveGetAttr(obj, most) |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
313 |
setattr(parent, last, value) |
7854ddd0fc30
Fixed recursive import, setting and gettign attributes
andy_robinson
parents:
1683
diff
changeset
|
314 |
|
674 | 315 |
def import_zlib(): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
316 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
317 |
import zlib |
2053 | 318 |
except ImportError: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
319 |
zlib = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
320 |
from reportlab.rl_config import ZLIB_WARNINGS |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
321 |
if ZLIB_WARNINGS: warnOnce('zlib not available') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
322 |
return zlib |
674 | 323 |
|
2045 | 324 |
# Image Capability Detection. Set a flag haveImages |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
325 |
# to tell us if either PIL or Java imaging libraries present. |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
326 |
# define PIL_Image as either None, or an alias for the PIL.Image |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
327 |
# module, as there are 2 ways to import it |
2045 | 328 |
if sys.platform[0:4] == 'java': |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
329 |
try: |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
330 |
import javax.imageio |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
331 |
import java.awt.image |
2045 | 332 |
haveImages = 1 |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
333 |
except: |
2045 | 334 |
haveImages = 0 |
335 |
else: |
|
336 |
try: |
|
337 |
from PIL import Image |
|
2053 | 338 |
except ImportError: |
2045 | 339 |
try: |
340 |
import Image |
|
2053 | 341 |
except ImportError: |
2045 | 342 |
Image = None |
343 |
haveImages = Image is not None |
|
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
344 |
|
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
345 |
try: |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
346 |
from cStringIO import StringIO as __StringIO |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
347 |
except ImportError: |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
348 |
from StringIO import StringIO as __StringIO |
1580 | 349 |
def getStringIO(buf=None): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
350 |
'''unified StringIO instance interface''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
351 |
return buf is not None and __StringIO(buf) or __StringIO() |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
352 |
_StringIOKlass=__StringIO().__class__ |
1580 | 353 |
|
1375 | 354 |
class ArgvDictValue: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
355 |
'''A type to allow clients of getArgvDict to specify a conversion function''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
356 |
def __init__(self,value,func): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
357 |
self.value = value |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
358 |
self.func = func |
1375 | 359 |
|
360 |
def getArgvDict(**kw): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
361 |
''' Builds a dictionary from its keyword arguments with overrides from sys.argv. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
362 |
Attempts to be smart about conversions, but the value can be an instance |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
363 |
of ArgDictValue to allow specifying a conversion function. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
364 |
''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
365 |
def handleValue(v,av,func): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
366 |
if func: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
367 |
v = func(av) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
368 |
else: |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
369 |
if isinstance(v,basestring): |
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
370 |
if isinstance(v,unicode): v = v.encode('utf8') |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
371 |
v = av |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
372 |
elif isinstance(v,float): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
373 |
v = float(av) |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
374 |
elif isinstance(v,int): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
375 |
v = int(av) |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
376 |
elif isinstance(v,list): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
377 |
v = list(eval(av)) |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
378 |
elif isinstance(v,tuple): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
379 |
v = tuple(eval(av)) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
380 |
else: |
3180
349e9644fce8
reportlab: attempt to remove type() checking in favour of isinstance
rgbecker
parents:
3171
diff
changeset
|
381 |
raise TypeError("Can't convert string %r to %s" % (av,type(v))) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
382 |
return v |
1387 | 383 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
384 |
A = sys.argv[1:] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
385 |
R = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
386 |
for k, v in kw.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
387 |
if isinstance(v,ArgvDictValue): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
388 |
v, func = v.value, v.func |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
389 |
else: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
390 |
func = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
391 |
handled = 0 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
392 |
ke = k+'=' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
393 |
for a in A: |
3134 | 394 |
if a.find(ke)==0: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
395 |
av = a[len(ke):] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
396 |
A.remove(a) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
397 |
R[k] = handleValue(v,av,func) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
398 |
handled = 1 |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
399 |
break |
1387 | 400 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
401 |
if not handled: R[k] = handleValue(v,v,func) |
1387 | 402 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
403 |
return R |
1375 | 404 |
|
452 | 405 |
def getHyphenater(hDict=None): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
406 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
407 |
from reportlab.lib.pyHnj import Hyphen |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
408 |
if hDict is None: hDict=os.path.join(os.path.dirname(__file__),'hyphen.mashed') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
409 |
return Hyphen(hDict) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
410 |
except ImportError, errMsg: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
411 |
if str(errMsg)!='No module named pyHnj': raise |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
412 |
return None |
452 | 413 |
|
448 | 414 |
def _className(self): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
415 |
'''Return a shortened class name''' |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
416 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
417 |
name = self.__class__.__name__ |
3134 | 418 |
i=name.rfind('.') |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
419 |
if i>=0: return name[i+1:] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
420 |
return name |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
421 |
except AttributeError: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
422 |
return str(self) |
1538 | 423 |
|
2309 | 424 |
def open_for_read_by_name(name,mode='b'): |
425 |
if 'r' not in mode: mode = 'r'+mode |
|
426 |
try: |
|
427 |
return open(name,mode) |
|
428 |
except IOError: |
|
429 |
if _isFSD or __loader__ is None: raise |
|
2313 | 430 |
#we have a __loader__, perhaps the filename starts with |
431 |
#the dirname(reportlab.__file__) or is relative |
|
432 |
name = _startswith_rl(name) |
|
433 |
s = __loader__.get_data(name) |
|
434 |
if 'b' not in mode and os.linesep!='\n': s = s.replace(os.linesep,'\n') |
|
435 |
return getStringIO(s) |
|
2309 | 436 |
|
3327 | 437 |
import urllib2 |
438 |
def open_for_read(name,mode='b', urlopen=urllib2.urlopen): |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
439 |
'''attempt to open a file or URL for reading''' |
2229 | 440 |
if hasattr(name,'read'): return name |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
441 |
try: |
2313 | 442 |
return open_for_read_by_name(name,mode) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
443 |
except: |
2313 | 444 |
try: |
445 |
return getStringIO(urlopen(name).read()) |
|
446 |
except: |
|
447 |
raise IOError('Cannot open resource "%s"' % name) |
|
3327 | 448 |
del urllib2 |
1575 | 449 |
|
2225 | 450 |
def open_and_read(name,mode='b'): |
451 |
return open_for_read(name,mode).read() |
|
452 |
||
2247 | 453 |
def open_and_readlines(name,mode='t'): |
454 |
return open_and_read(name,mode).split('\n') |
|
455 |
||
2240 | 456 |
def rl_isfile(fn,os_path_isfile=os.path.isfile): |
457 |
if hasattr(fn,'read'): return True |
|
458 |
if os_path_isfile(fn): return True |
|
459 |
if _isFSD or __loader__ is None: return False |
|
2244 | 460 |
fn = _startswith_rl(fn) |
461 |
return fn in __loader__._files.keys() |
|
2240 | 462 |
|
2339
4b1dae4bd1a8
More changes related to compact distro path recognition
rgbecker
parents:
2332
diff
changeset
|
463 |
def rl_isdir(pn,os_path_isdir=os.path.isdir,os_path_normpath=os.path.normpath): |
2244 | 464 |
if os_path_isdir(pn): return True |
465 |
if _isFSD or __loader__ is None: return False |
|
2354 | 466 |
pn = _startswith_rl(os_path_normpath(pn)) |
467 |
if not pn.endswith(os.sep): pn += os.sep |
|
2258 | 468 |
return len(filter(lambda x,pn=pn: x.startswith(pn),__loader__._files.keys()))>0 |
2240 | 469 |
|
2794 | 470 |
def rl_listdir(pn,os_path_isdir=os.path.isdir,os_path_normpath=os.path.normpath,os_listdir=os.listdir): |
471 |
if os_path_isdir(pn) or _isFSD or __loader__ is None: return os_listdir(pn) |
|
472 |
pn = _startswith_rl(os_path_normpath(pn)) |
|
473 |
if not pn.endswith(os.sep): pn += os.sep |
|
474 |
return [x[len(pn):] for x in __loader__._files.keys() if x.startswith(pn)] |
|
475 |
||
476 |
def rl_getmtime(pn,os_path_isfile=os.path.isfile,os_path_normpath=os.path.normpath,os_path_getmtime=os.path.getmtime,time_mktime=time.mktime): |
|
477 |
if os_path_isfile(pn) or _isFSD or __loader__ is None: return os_path_getmtime(pn) |
|
478 |
p = _startswith_rl(os_path_normpath(pn)) |
|
479 |
try: |
|
480 |
e = __loader__._files[p] |
|
481 |
except KeyError: |
|
482 |
return os_path_getmtime(pn) |
|
483 |
s = e[5] |
|
484 |
d = e[6] |
|
3569 | 485 |
return time_mktime((((d>>9)&0x7f)+1980,(d>>5)&0xf,d&0x1f,(s>>11)&0x1f,(s>>5)&0x3f,(s&0x1f)<<1,0,0,0)) |
2794 | 486 |
|
2301 | 487 |
def rl_get_module(name,dir): |
3326 | 488 |
if name in sys.modules: |
2301 | 489 |
om = sys.modules[name] |
490 |
del sys.modules[name] |
|
491 |
else: |
|
492 |
om = None |
|
493 |
try: |
|
2302 | 494 |
f = None |
2301 | 495 |
try: |
2302 | 496 |
f, p, desc= imp.find_module(name,[dir]) |
2301 | 497 |
return imp.load_module(name,f,p,desc) |
498 |
except: |
|
2307 | 499 |
if isCompactDistro(): |
2301 | 500 |
#attempt a load from inside the zip archive |
501 |
import zipimport |
|
2307 | 502 |
dir = _startswith_rl(dir) |
2356 | 503 |
dir = (dir=='.' or not dir) and _archive or os.path.join(_archive,dir.replace('/',os.sep)) |
2327
c40a1b477f3f
Forgot to check the exactly equal case for _startswith_rl
rgbecker
parents:
2313
diff
changeset
|
504 |
zi = zipimport.zipimporter(dir) |
2301 | 505 |
return zi.load_module(name) |
506 |
raise ImportError('%s[%s]' % (name,dir)) |
|
507 |
finally: |
|
508 |
if om: sys.modules[name] = om |
|
509 |
del om |
|
510 |
if f: f.close() |
|
511 |
||
2487 | 512 |
def _isPILImage(im): |
513 |
try: |
|
3291 | 514 |
return isinstance(im,Image.Image) |
3465
21c2d12661b9
utils.py: fix exception class and use annotateException
rgbecker
parents:
3437
diff
changeset
|
515 |
except AttributeError: |
2487 | 516 |
return 0 |
517 |
||
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
518 |
class ImageReader(object): |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
519 |
"Wraps up either PIL or Java to get data from bitmaps" |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
520 |
_cache={} |
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
521 |
def __init__(self, fileName,ident=None): |
2487 | 522 |
if isinstance(fileName,ImageReader): |
523 |
self.__dict__ = fileName.__dict__ #borgize |
|
524 |
return |
|
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
525 |
self._ident = ident |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
526 |
#start wih lots of null private fields, to be populated by |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
527 |
#the relevant engine. |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
528 |
self.fileName = fileName |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
529 |
self._image = None |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
530 |
self._width = None |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
531 |
self._height = None |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
532 |
self._transparent = None |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
533 |
self._data = None |
2487 | 534 |
if _isPILImage(fileName): |
535 |
self._image = fileName |
|
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
536 |
self.fp = getattr(fileName,'fp',None) |
2487 | 537 |
try: |
2720
2c04d204766d
utils.py: attempt to fix fileName from PIL images
rgbecker
parents:
2716
diff
changeset
|
538 |
self.fileName = self._image.fileName |
2487 | 539 |
except AttributeError: |
540 |
self.fileName = 'PILIMAGE_%d' % id(self) |
|
541 |
else: |
|
2556 | 542 |
try: |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
543 |
from reportlab.rl_config import imageReaderFlags |
2556 | 544 |
self.fp = open_for_read(fileName,'b') |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
545 |
if isinstance(self.fp,_StringIOKlass): imageReaderFlags=0 #avoid messing with already internal files |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
546 |
if imageReaderFlags>0: #interning |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
547 |
data = self.fp.read() |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
548 |
if imageReaderFlags&2: #autoclose |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
549 |
try: |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
550 |
self.fp.close() |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
551 |
except: |
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
552 |
pass |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
553 |
if imageReaderFlags&4: #cache the data |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
554 |
if not self._cache: |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
555 |
from rl_config import register_reset |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
556 |
register_reset(self._cache.clear) |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
557 |
data=self._cache.setdefault(md5(data).digest(),data) |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
558 |
self.fp=getStringIO(data) |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
559 |
elif imageReaderFlags==-1 and isinstance(fileName,(str,unicode)): |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
560 |
#try Ralf Schmitt's re-opening technique of avoiding too many open files |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
561 |
self.fp.close() |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
562 |
del self.fp #will become a property in the next statement |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
563 |
self.__class__=LazyImageReader |
2953
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
564 |
if haveImages: |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
565 |
#detect which library we are using and open the image |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
566 |
if not self._image: |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
567 |
self._image = self._read_image(self.fp) |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
568 |
if getattr(self._image,'format',None)=='JPEG': self.jpeg_fh = self._jpeg_fh |
2953
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
569 |
else: |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
570 |
from reportlab.pdfbase.pdfutils import readJPEGInfo |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
571 |
try: |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
572 |
self._width,self._height,c=readJPEGInfo(self.fp) |
2952
8a51cf037687
reportlab: add rl_config.internImageFiles and extra support in ImageReader
rgbecker
parents:
2942
diff
changeset
|
573 |
except: |
3465
21c2d12661b9
utils.py: fix exception class and use annotateException
rgbecker
parents:
3437
diff
changeset
|
574 |
annotateException('\nImaging Library not available, unable to import bitmaps only jpegs\nfileName=%r identity=%s'%(fileName,self.identity())) |
2953
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
575 |
self.jpeg_fh = self._jpeg_fh |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
576 |
self._data = self.fp.read() |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
577 |
self._dataA=None |
59f221d6007c
reportlab: improve ImageReader so it works with Image flowables in the absence of PIL
rgbecker
parents:
2952
diff
changeset
|
578 |
self.fp.seek(0) |
2556 | 579 |
except: |
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
580 |
annotateException('\nfileName=%r identity=%s'%(fileName,self.identity())) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
581 |
|
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
582 |
def identity(self): |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
583 |
'''try to return information that will identify the instance''' |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
584 |
fn = self.fileName |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
585 |
if not isinstance(fn,basestring): |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
586 |
fn = getattr(getattr(self,'fp',None),'name',None) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
587 |
ident = self._ident |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
588 |
return '[%s@%s%s%s]' % (self.__class__.__name__,hex(id(self)),ident and (' ident=%r' % ident) or '',fn and (' filename=%r' % fn) or '') |
2556 | 589 |
|
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
590 |
def _read_image(self,fp): |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
591 |
if sys.platform[0:4] == 'java': |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
592 |
from javax.imageio import ImageIO |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
593 |
return ImageIO.read(fp) |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
594 |
else: |
3291 | 595 |
return Image.open(fp) |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
596 |
|
2487 | 597 |
def _jpeg_fh(self): |
598 |
fp = self.fp |
|
599 |
fp.seek(0) |
|
600 |
return fp |
|
601 |
||
602 |
def jpeg_fh(self): |
|
603 |
return None |
|
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
604 |
|
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
605 |
def getSize(self): |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
606 |
if (self._width is None or self._height is None): |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
607 |
if sys.platform[0:4] == 'java': |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
608 |
self._width = self._image.getWidth() |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
609 |
self._height = self._image.getHeight() |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
610 |
else: |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
611 |
self._width, self._height = self._image.size |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
612 |
return (self._width, self._height) |
2200
be0cfccc662a
Fixed up tabs and whitespace in all source files
andy_robinson
parents:
2160
diff
changeset
|
613 |
|
2045 | 614 |
def getRGBData(self): |
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
615 |
"Return byte array of RGB data as string" |
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
616 |
try: |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
617 |
if self._data is None: |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
618 |
self._dataA = None |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
619 |
if sys.platform[0:4] == 'java': |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
620 |
import jarray |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
621 |
from java.awt.image import PixelGrabber |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
622 |
width, height = self.getSize() |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
623 |
buffer = jarray.zeros(width*height, 'i') |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
624 |
pg = PixelGrabber(self._image, 0,0,width,height,buffer,0,width) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
625 |
pg.grabPixels() |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
626 |
# there must be a way to do this with a cast not a byte-level loop, |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
627 |
# I just haven't found it yet... |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
628 |
pixels = [] |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
629 |
a = pixels.append |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
630 |
for i in range(len(buffer)): |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
631 |
rgb = buffer[i] |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
632 |
a(chr((rgb>>16)&0xff)) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
633 |
a(chr((rgb>>8)&0xff)) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
634 |
a(chr(rgb&0xff)) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
635 |
self._data = ''.join(pixels) |
2902
f15ac27dc73f
reportlab: add in RGBA functionality for sensible images
rgbecker
parents:
2838
diff
changeset
|
636 |
self.mode = 'RGB' |
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
637 |
else: |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
638 |
im = self._image |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
639 |
mode = self.mode = im.mode |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
640 |
if mode=='RGBA': |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
641 |
if Image.VERSION.startswith('1.1.7'): im.load() |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
642 |
self._dataA = ImageReader(im.split()[3]) |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
643 |
im = im.convert('RGB') |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
644 |
self.mode = 'RGB' |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
645 |
elif mode not in ('L','RGB','CMYK'): |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
646 |
im = im.convert('RGB') |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
647 |
self.mode = 'RGB' |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
648 |
self._data = im.tostring() |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
649 |
return self._data |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
650 |
except: |
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
651 |
annotateException('\nidentity=%s'%self.identity()) |
2045 | 652 |
|
653 |
def getImageData(self): |
|
654 |
width, height = self.getSize() |
|
655 |
return width, height, self.getRGBData() |
|
656 |
||
657 |
def getTransparent(self): |
|
658 |
if sys.platform[0:4] == 'java': |
|
659 |
return None |
|
660 |
else: |
|
3326 | 661 |
if "transparency" in self._image.info: |
2045 | 662 |
transparency = self._image.info["transparency"] * 3 |
663 |
palette = self._image.palette |
|
664 |
try: |
|
665 |
palette = palette.palette |
|
666 |
except: |
|
667 |
palette = palette.data |
|
668 |
return map(ord, palette[transparency:transparency+3]) |
|
669 |
else: |
|
670 |
return None |
|
671 |
||
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
672 |
class LazyImageReader(ImageReader): |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
673 |
def fp(self): |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
674 |
return open_for_read(self.fileName, 'b') |
3083 | 675 |
fp=property(fp) |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
676 |
|
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
677 |
def _image(self): |
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
678 |
return self._read_image(self.fp) |
3083 | 679 |
_image=property(_image) |
2954
5ec6485e810a
reportlab: implement Ralf Schmitt's open files limiter
rgbecker
parents:
2953
diff
changeset
|
680 |
|
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
681 |
def getImageData(imageFileName): |
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
682 |
"Get width, height and RGB pixels from image file. Wraps Java/PIL" |
2487 | 683 |
try: |
684 |
return imageFileName.getImageData() |
|
685 |
except AttributeError: |
|
686 |
return ImageReader(imageFileName).getImageData() |
|
2044
3be472f4a6dd
Various work on abstracting out images, plus outstanding patches
andy_robinson
parents:
2007
diff
changeset
|
687 |
|
1538 | 688 |
class DebugMemo: |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
689 |
'''Intended as a simple report back encapsulator |
1545 | 690 |
|
3028
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
691 |
Typical usages: |
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
692 |
|
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
693 |
1. To record error data:: |
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
694 |
|
1683 | 695 |
dbg = DebugMemo(fn='dbgmemo.dbg',myVar=value) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
696 |
dbg.add(anotherPayload='aaaa',andagain='bbb') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
697 |
dbg.dump() |
1543
3681c7d8898d
Slight formatting improvements & added payload method
rgbecker
parents:
1538
diff
changeset
|
698 |
|
3028
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
699 |
2. To show the recorded info:: |
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
700 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
701 |
dbg = DebugMemo(fn='dbgmemo.dbg',mode='r') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
702 |
dbg.load() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
703 |
dbg.show() |
1543
3681c7d8898d
Slight formatting improvements & added payload method
rgbecker
parents:
1538
diff
changeset
|
704 |
|
3028
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
705 |
3. To re-use recorded information:: |
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
706 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
707 |
dbg = DebugMemo(fn='dbgmemo.dbg',mode='r') |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
708 |
dbg.load() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
709 |
myTestFunc(dbg.payload('myVar'),dbg.payload('andagain')) |
1545 | 710 |
|
3028
082f5208644e
docstring modifications to adhere to restructuredtext
damian
parents:
2964
diff
changeset
|
711 |
In addition to the payload variables the dump records many useful bits |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
712 |
of information which are also printed in the show() method. |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
713 |
''' |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
714 |
def __init__(self,fn='rl_dbgmemo.dbg',mode='w',getScript=1,modules=(),capture_traceback=1, stdout=None, **kw): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
715 |
import time, socket |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
716 |
self.fn = fn |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
717 |
if not stdout: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
718 |
self.stdout = sys.stdout |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
719 |
else: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
720 |
if hasattr(stdout,'write'): |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
721 |
self.stdout = stdout |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
722 |
else: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
723 |
self.stdout = open(stdout,'w') |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
724 |
if mode!='w': return |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
725 |
self.store = store = {} |
2296 | 726 |
if capture_traceback and sys.exc_info() != (None,None,None): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
727 |
import traceback |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
728 |
s = getStringIO() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
729 |
traceback.print_exc(None,s) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
730 |
store['__traceback'] = s.getvalue() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
731 |
cwd=os.getcwd() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
732 |
lcwd = os.listdir(cwd) |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
733 |
pcwd = os.path.dirname(cwd) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
734 |
lpcwd = pcwd and os.listdir(pcwd) or '???' |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
735 |
exed = os.path.abspath(os.path.dirname(sys.argv[0])) |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
736 |
project_version='???' |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
737 |
md=None |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
738 |
try: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
739 |
import marshal |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
740 |
md=marshal.loads(__loader__.get_data('meta_data.mar')) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
741 |
project_version=md['project_version'] |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
742 |
except: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
743 |
pass |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
744 |
env = os.environ |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
745 |
K=env.keys() |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
746 |
K.sort() |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
747 |
store.update({ 'gmt': time.asctime(time.gmtime(time.time())), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
748 |
'platform': sys.platform, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
749 |
'version': sys.version, |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
750 |
'hexversion': hex(sys.hexversion), |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
751 |
'executable': sys.executable, |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
752 |
'exec_prefix': sys.exec_prefix, |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
753 |
'prefix': sys.prefix, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
754 |
'path': sys.path, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
755 |
'argv': sys.argv, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
756 |
'cwd': cwd, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
757 |
'hostname': socket.gethostname(), |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
758 |
'lcwd': lcwd, |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
759 |
'lpcwd': lpcwd, |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
760 |
'byteorder': sys.byteorder, |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
761 |
'maxint': sys.maxint, |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
762 |
'maxint': getattr(sys,'maxunicode','????'), |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
763 |
'api_version': getattr(sys,'api_version','????'), |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
764 |
'version_info': getattr(sys,'version_info','????'), |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
765 |
'winver': getattr(sys,'winver','????'), |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
766 |
'environment': '\n\t\t\t'.join(['']+['%s=%r' % (k,env[k]) for k in K]), |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
767 |
'__loader__': repr(__loader__), |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
768 |
'project_meta_data': md, |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
769 |
'project_version': project_version, |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
770 |
}) |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
771 |
for M,A in ( |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
772 |
(sys,('getwindowsversion','getfilesystemencoding')), |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
773 |
(os,('uname', 'ctermid', 'getgid', 'getuid', 'getegid', |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
774 |
'geteuid', 'getlogin', 'getgroups', 'getpgrp', 'getpid', 'getppid', |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
775 |
)), |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
776 |
): |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
777 |
for a in A: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
778 |
if hasattr(M,a): |
2300 | 779 |
try: |
780 |
store[a] = getattr(M,a)() |
|
781 |
except: |
|
782 |
pass |
|
783 |
if exed!=cwd: |
|
784 |
try: |
|
785 |
store.update({'exed': exed, 'lexed': os.listdir(exed),}) |
|
786 |
except: |
|
787 |
pass |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
788 |
if getScript: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
789 |
fn = os.path.abspath(sys.argv[0]) |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
790 |
if os.path.isfile(fn): |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
791 |
try: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
792 |
store['__script'] = (fn,open(fn,'r').read()) |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
793 |
except: |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
794 |
pass |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
795 |
module_versions = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
796 |
for n,m in sys.modules.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
797 |
if n=='reportlab' or n=='rlextra' or n[:10]=='reportlab.' or n[:8]=='rlextra.': |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
798 |
v = [getattr(m,x,None) for x in ('__version__','__path__','__file__')] |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
799 |
if filter(None,v): |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
800 |
v = [v[0]] + filter(None,v[1:]) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
801 |
module_versions[n] = tuple(v) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
802 |
store['__module_versions'] = module_versions |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
803 |
self.store['__payload'] = {} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
804 |
self._add(kw) |
1538 | 805 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
806 |
def _add(self,D): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
807 |
payload = self.store['__payload'] |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
808 |
for k, v in D.items(): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
809 |
payload[k] = v |
1538 | 810 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
811 |
def add(self,**kw): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
812 |
self._add(kw) |
1538 | 813 |
|
2942
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
814 |
def _dump(self,f): |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
815 |
import pickle |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
816 |
try: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
817 |
pos=f.tell() |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
818 |
pickle.dump(self.store,f) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
819 |
except: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
820 |
S=self.store.copy() |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
821 |
ff=getStringIO() |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
822 |
for k,v in S.iteritems(): |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
823 |
try: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
824 |
pickle.dump({k:v},ff) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
825 |
except: |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
826 |
S[k] = '<unpicklable object %r>' % v |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
827 |
f.seek(pos,0) |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
828 |
pickle.dump(S,f) |
2942
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
829 |
|
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
830 |
def dump(self): |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
831 |
f = open(self.fn,'wb') |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
832 |
try: |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
833 |
self._dump(f) |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
834 |
finally: |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
835 |
f.close() |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
836 |
|
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
837 |
def dumps(self): |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
838 |
f = getStringIO() |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
839 |
self._dump(f) |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
840 |
return f.getvalue() |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
841 |
|
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
842 |
def _load(self,f): |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
843 |
import pickle |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
844 |
self.store = pickle.load(f) |
1538 | 845 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
846 |
def load(self): |
2942
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
847 |
f = open(self.fn,'rb') |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
848 |
try: |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
849 |
self._load(f) |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
850 |
finally: |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
851 |
f.close() |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
852 |
|
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
853 |
def loads(self,s): |
e6e20484c315
reportlab/lib/utils.py: slight extensions to DebugMemo
rgbecker
parents:
2929
diff
changeset
|
854 |
self._load(getStringIO(s)) |
1538 | 855 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
856 |
def _show_module_versions(self,k,v): |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
857 |
self._writeln(k[2:]) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
858 |
K = v.keys() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
859 |
K.sort() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
860 |
for k in K: |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
861 |
vk = vk0 = v[k] |
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
862 |
if isinstance(vk,tuple): vk0 = vk[0] |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
863 |
try: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
864 |
m = recursiveImport(k,sys.path[:],1) |
3205
c65681e50856
utils.py: attempt to bring DebugMemo into line with nomt branch version
rgbecker
parents:
3180
diff
changeset
|
865 |
d = getattr(m,'__version__',None)==vk0 and 'SAME' or 'DIFFERENT' |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
866 |
except: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
867 |
m = None |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
868 |
d = '??????unknown??????' |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
869 |
self._writeln(' %s = %s (%s)' % (k,vk,d)) |
1538 | 870 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
871 |
def _banner(self,k,what): |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
872 |
self._writeln('###################%s %s##################' % (what,k[2:])) |
1538 | 873 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
874 |
def _start(self,k): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
875 |
self._banner(k,'Start ') |
1538 | 876 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
877 |
def _finish(self,k): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
878 |
self._banner(k,'Finish ') |
1538 | 879 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
880 |
def _show_lines(self,k,v): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
881 |
self._start(k) |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
882 |
self._writeln(v) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
883 |
self._finish(k) |
1538 | 884 |
|
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
885 |
def _show_file(self,k,v): |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
886 |
k = '%s %s' % (k,os.path.basename(v[0])) |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
887 |
self._show_lines(k,v[1]) |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
888 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
889 |
def _show_payload(self,k,v): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
890 |
if v: |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
891 |
import pprint |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
892 |
self._start(k) |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
893 |
pprint.pprint(v,self.stdout) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
894 |
self._finish(k) |
1538 | 895 |
|
3122 | 896 |
def _show_extensions(self): |
897 |
for mn in ('_rl_accel','_renderPM','sgmlop','pyRXP','pyRXPU','_imaging','Image'): |
|
898 |
try: |
|
899 |
A = [mn].append |
|
900 |
m = recursiveImport(mn,sys.path[:],1) |
|
901 |
A(m.__file__) |
|
902 |
for vn in ('__version__','VERSION','_version','version'): |
|
903 |
if hasattr(m,vn): |
|
904 |
A('%s=%r' % (vn,getattr(m,vn))) |
|
905 |
except: |
|
906 |
A('not found') |
|
907 |
self._writeln(' '+' '.join(A.__self__)) |
|
908 |
||
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
909 |
specials = {'__module_versions': _show_module_versions, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
910 |
'__payload': _show_payload, |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
911 |
'__traceback': _show_lines, |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
912 |
'__script': _show_file, |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
913 |
} |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
914 |
def show(self): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
915 |
K = self.store.keys() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
916 |
K.sort() |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
917 |
for k in K: |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
918 |
if k not in self.specials.keys(): self._writeln('%-15s = %s' % (k,self.store[k])) |
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
919 |
for k in K: |
3122 | 920 |
if k in self.specials.keys(): self.specials[k](self,k,self.store[k]) |
921 |
self._show_extensions() |
|
1543
3681c7d8898d
Slight formatting improvements & added payload method
rgbecker
parents:
1538
diff
changeset
|
922 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
923 |
def payload(self,name): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
924 |
return self.store['__payload'][name] |
1561 | 925 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
926 |
def __setitem__(self,name,value): |
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
927 |
self.store['__payload'][name] = value |
1561 | 928 |
|
1677
1450177dd19e
Exterminated all tab characters and added a test to make sure
andy_robinson
parents:
1650
diff
changeset
|
929 |
def __getitem__(self,name): |
1833
135322abc191
Fix recursivImport for case when baseDir is a sequence
rgbecker
parents:
1821
diff
changeset
|
930 |
return self.store['__payload'][name] |
2297
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
931 |
|
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
932 |
def _writeln(self,msg): |
7c706ac8a6b7
Added some more stuff and script name to DebugMemo output
rgbecker
parents:
2296
diff
changeset
|
933 |
self.stdout.write(msg+'\n') |
2365
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
934 |
|
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
935 |
def _flatten(L,a): |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
936 |
for x in L: |
2499 | 937 |
if isSeqType(x): _flatten(x,a) |
2365
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
938 |
else: a(x) |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
939 |
|
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
940 |
def flatten(L): |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
941 |
'''recursively flatten the list or tuple L''' |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
942 |
R = [] |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
943 |
_flatten(L,R.append) |
cda528e430aa
reportlab/lib/utils.py: added flatten utility function
rgbecker
parents:
2356
diff
changeset
|
944 |
return R |
2406 | 945 |
|
946 |
def find_locals(func,depth=0): |
|
947 |
'''apply func to the locals at each stack frame till func returns a non false value''' |
|
948 |
while 1: |
|
949 |
_ = func(sys._getframe(depth).f_locals) |
|
950 |
if _: return _ |
|
951 |
depth += 1 |
|
2454 | 952 |
|
953 |
class _FmtSelfDict: |
|
2479 | 954 |
def __init__(self,obj,overrideArgs): |
2454 | 955 |
self.obj = obj |
2479 | 956 |
self._overrideArgs = overrideArgs |
2454 | 957 |
def __getitem__(self,k): |
958 |
try: |
|
2479 | 959 |
return self._overrideArgs[k] |
2454 | 960 |
except KeyError: |
2479 | 961 |
try: |
962 |
return self.obj.__dict__[k] |
|
963 |
except KeyError: |
|
964 |
return getattr(self.obj,k) |
|
2454 | 965 |
|
966 |
class FmtSelfDict: |
|
967 |
'''mixin to provide the _fmt method''' |
|
2479 | 968 |
def _fmt(self,fmt,**overrideArgs): |
969 |
D = _FmtSelfDict(self, overrideArgs) |
|
2454 | 970 |
return fmt % D |
2715 | 971 |
|
2716 | 972 |
def _simpleSplit(txt,mW,SW): |
973 |
L = [] |
|
974 |
ws = SW(' ') |
|
975 |
O = [] |
|
976 |
w = -ws |
|
977 |
for t in txt.split(): |
|
978 |
lt = SW(t) |
|
979 |
if w+ws+lt<=mW or O==[]: |
|
980 |
O.append(t) |
|
981 |
w = w + ws + lt |
|
982 |
else: |
|
3134 | 983 |
L.append(' '.join(O)) |
2716 | 984 |
O = [t] |
985 |
w = lt |
|
3134 | 986 |
if O!=[]: L.append(' '.join(O)) |
2716 | 987 |
return L |
988 |
||
2715 | 989 |
def simpleSplit(text,fontName,fontSize,maxWidth): |
2716 | 990 |
from reportlab.pdfbase.pdfmetrics import stringWidth |
2715 | 991 |
lines = text.split('\n') |
992 |
SW = lambda text, fN=fontName, fS=fontSize: stringWidth(text, fN, fS) |
|
993 |
if maxWidth: |
|
994 |
L = [] |
|
995 |
for l in lines: |
|
996 |
L[-1:-1] = _simpleSplit(l,maxWidth,SW) |
|
997 |
lines = L |
|
998 |
return lines |
|
2764 | 999 |
|
1000 |
def escapeTextOnce(text): |
|
1001 |
"Escapes once only" |
|
1002 |
from xml.sax.saxutils import escape |
|
1003 |
if text is None: |
|
1004 |
return text |
|
1005 |
text = escape(text) |
|
1006 |
text = text.replace('&amp;', '&') |
|
1007 |
text = text.replace('&gt;', '>') |
|
1008 |
text = text.replace('&lt;', '<') |
|
1009 |
return text |
|
1010 |
||
2813
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1011 |
def fileName2Utf8(fn): |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1012 |
'''attempt to convert a filename to utf8''' |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1013 |
from reportlab.rl_config import fsEncodings |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1014 |
for enc in fsEncodings: |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1015 |
try: |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1016 |
return fn.decode(enc).encode('utf8') |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1017 |
except: |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1018 |
pass |
2b9091df4470
reportlab: add fsEncodings to rl_config, add fileName2Utf8
rgbecker
parents:
2794
diff
changeset
|
1019 |
raise ValueError('cannot convert %r to utf8' % fn) |
2929 | 1020 |
|
1021 |
||
1022 |
import itertools |
|
1023 |
def prev_this_next(items): |
|
1024 |
""" |
|
1025 |
Loop over a collection with look-ahead and look-back. |
|
1026 |
||
1027 |
From Thomas Guest, |
|
1028 |
http://wordaligned.org/articles/zippy-triples-served-with-python |
|
1029 |
||
1030 |
Seriously useful looping tool (Google "zippy triples") |
|
1031 |
lets you loop a collection and see the previous and next items, |
|
1032 |
which get set to None at the ends. |
|
1033 |
||
1034 |
To be used in layout algorithms where one wants a peek at the |
|
1035 |
next item coming down the pipe. |
|
1036 |
||
1037 |
""" |
|
1038 |
||
1039 |
extend = itertools.chain([None], items, [None]) |
|
1040 |
prev, this, next = itertools.tee(extend, 3) |
|
1041 |
try: |
|
1042 |
this.next() |
|
1043 |
next.next() |
|
1044 |
next.next() |
|
1045 |
except StopIteration: |
|
1046 |
pass |
|
1047 |
return itertools.izip(prev, this, next) |
|
3171
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1048 |
|
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1049 |
def commasplit(s): |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1050 |
''' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1051 |
Splits the string s at every unescaped comma and returns the result as a list. |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1052 |
To escape a comma, double it. Individual items are stripped. |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1053 |
To avoid the ambiguity of 3 successive commas to denote a comma at the beginning |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1054 |
or end of an item, add a space between the item seperator and the escaped comma. |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1055 |
|
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1056 |
>>> commasplit('a,b,c') |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1057 |
['a', 'b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1058 |
>>> commasplit('a,, , b , c ') |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1059 |
['a,', 'b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1060 |
>>> commasplit('a, ,,b, c') |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1061 |
['a', ',b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1062 |
''' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1063 |
n = len(s)-1 |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1064 |
s += ' ' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1065 |
i = 0 |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1066 |
r=[''] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1067 |
while i<=n: |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1068 |
if s[i]==',': |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1069 |
if s[i+1]==',': |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1070 |
r[-1]+=',' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1071 |
i += 1 |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1072 |
else: |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1073 |
r[-1] = r[-1].strip() |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1074 |
if i!=n: r.append('') |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1075 |
else: |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1076 |
r[-1] += s[i] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1077 |
i+=1 |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1078 |
r[-1] = r[-1].strip() |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1079 |
return r |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1080 |
|
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1081 |
def commajoin(l): |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1082 |
''' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1083 |
Inverse of commasplit, except that whitespace around items is not conserved. |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1084 |
Adds more whitespace than needed for simplicity and performance. |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1085 |
|
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1086 |
>>> commasplit(commajoin(['a', 'b', 'c'])) |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1087 |
['a', 'b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1088 |
>>> commasplit((commajoin(['a,', ' b ', 'c'])) |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1089 |
['a,', 'b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1090 |
>>> commasplit((commajoin(['a ', ',b', 'c'])) |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1091 |
['a', ',b', 'c'] |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1092 |
''' |
c94c900d9263
Better syntax for listing indexing terms inside an index paragraph tag attribute.
jonas
parents:
3134
diff
changeset
|
1093 |
return ','.join([ ' ' + i.replace(',', ',,') + ' ' for i in l ]) |
3213 | 1094 |
|
1095 |
def findInPaths(fn,paths,isfile=True,fail=False): |
|
1096 |
'''search for relative files in likely places''' |
|
1097 |
exists = isfile and os.path.isfile or os.path.isdir |
|
1098 |
if exists(fn): return fn |
|
1099 |
pjoin = os.path.join |
|
1100 |
if not os.path.isabs(fn): |
|
1101 |
for p in paths: |
|
1102 |
pfn = pjoin(p,fn) |
|
1103 |
if exists(pfn): |
|
1104 |
return pfn |
|
1105 |
if fail: raise ValueError('cannot locate %r with paths=%r' % (fn,paths)) |
|
1106 |
return fn |
|
3253 | 1107 |
|
1108 |
def annotateException(msg,enc='utf8'): |
|
1109 |
'''add msg to the args of an existing exception''' |
|
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
1110 |
if not msg: rise |
3253 | 1111 |
t,v,b=sys.exc_info() |
3355
cc00d31bc99e
utils.py: make ImageReader class a bit more useful when reporting errors
rgbecker
parents:
3349
diff
changeset
|
1112 |
if not hasattr(v,'args'): raise |
3253 | 1113 |
e = -1 |
1114 |
A = list(v.args) |
|
1115 |
for i,a in enumerate(A): |
|
1116 |
if isinstance(a,basestring): |
|
1117 |
e = i |
|
1118 |
break |
|
1119 |
if e>=0: |
|
1120 |
if isinstance(a,unicode): |
|
1121 |
if not isinstance(msg,unicode): |
|
1122 |
msg=msg.decode(enc) |
|
1123 |
else: |
|
1124 |
if isinstance(msg,unicode): |
|
1125 |
msg=msg.encode(enc) |
|
1126 |
else: |
|
1127 |
msg = str(msg) |
|
3437 | 1128 |
if isinstance(v,IOError) and getattr(v,'strerror',None): |
1129 |
v.strerror = msg+'\n'+str(v.strerror) |
|
3429
faa6425d8806
utils.py: attempted fix for IOError cases in annotateException
rgbecker
parents:
3355
diff
changeset
|
1130 |
else: |
faa6425d8806
utils.py: attempted fix for IOError cases in annotateException
rgbecker
parents:
3355
diff
changeset
|
1131 |
A[e] += msg |
3253 | 1132 |
else: |
1133 |
A.append(msg) |
|
1134 |
v.args = tuple(A) |
|
1135 |
raise t,v,b |
|
3349
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1136 |
|
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1137 |
def escapeOnce(data): |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1138 |
"""Ensure XML output is escaped just once, irrespective of input |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1139 |
|
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1140 |
>>> escapeOnce('A & B') |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1141 |
'A & B' |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1142 |
>>> escapeOnce('C & D') |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1143 |
'C & D' |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1144 |
>>> escapeOnce('E &amp; F') |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1145 |
'E & F' |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1146 |
|
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1147 |
""" |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1148 |
data = data.replace("&", "&") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1149 |
|
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1150 |
#...but if it was already escaped, make sure it |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1151 |
# is not done twice....this will turn any tags |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1152 |
# back to how they were at the start. |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1153 |
data = data.replace("&amp;", "&") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1154 |
data = data.replace("&gt;", ">") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1155 |
data = data.replace("&lt;", "<") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1156 |
data = data.replace("&#", "&#") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1157 |
|
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1158 |
#..and just in case someone had double-escaped it, do it again |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1159 |
data = data.replace("&amp;", "&") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1160 |
data = data.replace("&gt;", ">") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1161 |
data = data.replace("&lt;", "<") |
b67514b01536
Index display code now handles 'M&S'-like attributes however they are escaped
andy
parents:
3328
diff
changeset
|
1162 |
return data |
3517
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1163 |
|
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1164 |
class IdentStr(str): |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1165 |
'''useful for identifying things that get split''' |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1166 |
def __new__(cls,value): |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1167 |
if isinstance(value,IdentStr): |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1168 |
inc = value.__inc |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1169 |
value = value[:-(2+len(str(inc)))] |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1170 |
inc += 1 |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1171 |
else: |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1172 |
inc = 0 |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1173 |
value += '[%d]' % inc |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1174 |
self = str.__new__(cls,value) |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1175 |
self.__inc = inc |
d49ec5554d81
utils.py: add class IdentStr for incrementing strings
rgbecker
parents:
3465
diff
changeset
|
1176 |
return self |