1 from __future__
import with_statement
2 import os
, datetime
, thread
, re
, types
, sys
3 from settings
import Settings
4 _pid
= "[PID: %d] " % os
.getpid()
5 _pid
= _pid
+ " " * (12 - len(_pid
))
7 if Settings
.disableAllLogging
:
9 assert type(msg
) == str or type(msg
) == unicode
12 with
open(os
.path
.sep
.join( __file__
.split(os
.path
.sep
)[:-1] + ["limo.log"] ), "a") as f
:
17 if Settings
.profileServer
:
18 if( isinstance(name
, types
.FunctionType
) ):
19 # if the first arg is a function,
20 # we are called as a decorator,
21 # so add some named profile calls around the function
23 profile('function:'+name
.__name
__)
24 ret
= name(*args
,**kw
)
25 profile('function:'+name
.__name
__)
28 # else, we are called in the old-fashioned way
29 id = thread
.get_ident() # profiling is stored per-thread
30 if _profiles
.get(id, False) is False:
32 if _profiles
[id].get(name
, False) is False:
33 _profiles
[id][name
] = datetime
.datetime
.now()
35 ret
= ms_elapsed(_profiles
[id][name
])
36 del _profiles
[id][name
]
40 class Loggable(object):
42 log("%s: %s" % (self
.__class
__.__name
__, msg
))
44 def ms_elapsed(since
):
45 d
= (datetime
.datetime
.now() - since
)
46 return (d
.seconds
*1000.0) + (d
.microseconds
/ 1000.0)
49 assert type(s
) in (str, unicode), "urlescape() only works on strings"
50 return s
.replace("<","<").replace(">",">")
52 def ellipsis(text
, maxlen
, endsize
=7):
53 """ ellipsis is a helper function provided to all templates.
54 It grabs a little off both ends and puts an ellipsis in the middle.
56 >>> ellipsis("1234567890_2_4_6_8_01_3_5_7_9_", 20)
58 >>> ellipsis("1234567890", 8, 2)
60 >>> len(ellipsis("1234567890", 8, 2))
64 if type(text
) not in (str,unicode):
66 assert type(text
) in (str, unicode)
67 if len(text
) <= maxlen
:
70 return text
[0:maxlen
-3]+"..."
71 return text
[0:maxlen
-(endsize
+3)]+"..."+text
[-endsize
:]
73 def pad(text
, minlen
, fillchar
=' '):
74 return text
+ fillchar
* (minlen
- len(text
))
77 assert type(s
) == str, "urlencode() only works on strings"
78 ret
= cStringIO
.StringIO()
81 ret
.write("%%%s" % hex(ord(c
))[2:])
87 """ urldecode is a helper function provided to all templates.
88 >>> urldecode("Text%21")
91 f
= re
.search(r
"%([A-Za-z0-9]+)", text
)
94 return urldecode(text
[:pos
-1] + chr(int(text
[pos
:pos
+2], 16)) + text
[pos
+2:])
96 return text
.replace("+", " ")
99 return '"' + '"\n\t+ "'.join(str(s
).replace("\\","\\\\").replace('"','\\"').splitlines()) + '"'
102 if hasattr(obj
, "__json__"):
103 return obj
.__json
__()
106 if t
in (str, unicode):
108 elif t
in (int,float,long):
110 elif t
in (types
.GeneratorType
, list, tuple):
111 return '['+", ".join([json(x
) for x
in obj
])+']'
112 elif t
== types
.NoneType
:
115 return '{'+', '.join(["%s: %s" % (k
,json(v
)) for k
,v
in obj
.items()])+'}'
116 elif classInheritsFrom(t
, 'Exception'):
118 (a
,b
,c
) = sys
.exc_info()
119 tb
= traceback
.format_tb(c
)
121 return ";(function(){ var _e = new Error("+quoted(obj
)+"); _e.stack = ["+','.join([quoted(x
) for x
in tb
])+"]; throw _e; })();"
123 def classInheritsFrom(obj
, classname
):
124 if not hasattr(obj
, '__bases__'):
126 for c
in obj
.__bases
__:
127 if c
.__name
__ == classname
:
129 for c
in obj
.__bases
__:
130 if classInheritsFrom(c
, classname
):
135 if hasattr(c
, '__class__'):
136 return c
.__class
__.__name
__