added 2 missing template files
[limo.git] / limoutil.py
blobff49bb828823f377ff95ace1da1b6d30fbe14dd8
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))
6 def log(msg):
7 if Settings.disableAllLogging:
8 return
9 assert type(msg) == str or type(msg) == unicode
10 if msg[-1] <> "\n":
11 msg += "\n"
12 with open(os.path.sep.join( __file__.split(os.path.sep)[:-1] + ["limo.log"] ), "a") as f:
13 f.write(_pid + msg)
15 _profiles = {}
16 def profile(name):
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
22 def new(*args,**kw):
23 profile('function:'+name.__name__)
24 ret = name(*args,**kw)
25 profile('function:'+name.__name__)
26 return ret
27 return new
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:
31 _profiles[id] = {}
32 if _profiles[id].get(name, False) is False:
33 _profiles[id][name] = datetime.datetime.now()
34 else:
35 ret = ms_elapsed(_profiles[id][name])
36 del _profiles[id][name]
37 return ret
38 return None
40 class Loggable(object):
41 def log(self, msg):
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)
48 def htmlescape(s):
49 assert type(s) in (str, unicode), "urlescape() only works on strings"
50 return s.replace("<","&lt;").replace(">","&gt;")
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)
57 1234567890..._5_7_9_
58 >>> ellipsis("1234567890", 8, 2)
59 123...90
60 >>> len(ellipsis("1234567890", 8, 2))
63 """
64 if type(text) not in (str,unicode):
65 text = str(text)
66 assert type(text) in (str, unicode)
67 if len(text) <= maxlen:
68 return text
69 if endsize == 0:
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))
76 def urlencode(s):
77 assert type(s) == str, "urlencode() only works on strings"
78 ret = cStringIO.StringIO()
79 for c in s:
80 if not c.isalnum():
81 ret.write("%%%s" % hex(ord(c))[2:])
82 else:
83 ret.write(c)
84 return ret.getvalue()
86 def urldecode(text):
87 """ urldecode is a helper function provided to all templates.
88 >>> urldecode("Text%21")
89 Text!
90 """
91 f = re.search(r"%([A-Za-z0-9]+)", text)
92 if f is not None:
93 pos = f.start(1)
94 return urldecode(text[:pos-1] + chr(int(text[pos:pos+2], 16)) + text[pos+2:])
95 else:
96 return text.replace("+", " ")
98 def quoted(s):
99 return '"' + '"\n\t+ "'.join(str(s).replace("\\","\\\\").replace('"','\\"').splitlines()) + '"'
101 def json(obj):
102 if hasattr(obj, "__json__"):
103 return obj.__json__()
104 else:
105 t = type(obj)
106 if t in (str, unicode):
107 return quoted(obj)
108 elif t in (int,float,long):
109 return str(obj)
110 elif t in (types.GeneratorType, list, tuple):
111 return '['+", ".join([json(x) for x in obj])+']'
112 elif t == types.NoneType:
113 return "null"
114 elif t == dict:
115 return '{'+', '.join(["%s: %s" % (k,json(v)) for k,v in obj.items()])+'}'
116 elif classInheritsFrom(t, 'Exception'):
117 import traceback
118 (a,b,c) = sys.exc_info()
119 tb = traceback.format_tb(c)
120 del a,b,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__'):
125 return False
126 for c in obj.__bases__:
127 if c.__name__ == classname:
128 return True
129 for c in obj.__bases__:
130 if classInheritsFrom(c, classname):
131 return True
132 return False
134 def classname(c):
135 if hasattr(c, '__class__'):
136 return c.__class__.__name__
137 return None