Attachment 'ProgressBar.py'
Download 1 """
2 MoinMoin - ProgressBar Macro
3 Generates a progress bar (in the form of a table)
4
5 @copyright: Pascal Bauermeister <pascal DOT bauermeister AT gmail DOT cm>
6 @license: GPL
7
8 Updates:
9
10 * [v0.1.2] Tue Nov 21 20:54:59 CET 2006
11 Fixed the bar length errors (was a cell padding issue), works also
12 with IE. Thanks go to Thilo Pfennig for reporting the problem and
13 testing the fix.
14
15 * [v0.1.1] Sun Dec 18 21:31:17 CET 2005
16 Changed table cell percentage markup.
17
18 * [v0.1.0] Fri Dec 16 22:30:10 CET 2005
19 Original version
20
21 ----
22
23 The ProgressBar macro generates a table showing a progress indicator.
24
25 Usage:
26 [[ ProgressBar ]]
27 [[ ProgressBar (TABLEWIDTH TABLEFORMAT PROGRESS%) ]]
28 [[ ProgressBar (TABLEWIDTH TABLEFORMAT CURRENT/STEPS) ]]
29 [[ ProgressBar (TABLEWIDTH TABLEFORMAT STARTDATE,ENDDATE) ]]
30
31 If no arguments are given, the usage is inserted in the HTML result.
32
33 Options:
34
35 TABLEWIDTH (optional prefix)
36 A wiki tablewidth attribute value between []'s
37 Examples:
38 [100%]
39 [80px]
40
41 TABLEFORMAT (optional prefix)
42 A pair of wiki table attribute, to format the inactive and active cells.
43 Examples:
44 <bgcolor="black"><bgcolor="white"> # black on white bar
45 <tablewidth="90%" bgcolor="black"><bgcolor="white"> # same, 90% table
46
47 A third format may be given for STARTDATE,ENDDATE usage
48
49 By default: <tablewidth="100px"#808080><><#8080ff>
50
51 PROGRESS
52 Will display a table with two cells:
53 - left: completion, taking PROGRESS % of the table width
54 - right: remaining
55
56 By default, the table is 100px wide.
57
58 CURRENT/STEPS
59 Will display a table with STEPS cells, CURRENT of which are active.
60
61 By default, each cell is 0.5em wide, unless the table width is
62 specified.
63
64 STARTDATE,ENDDATE
65 Will display a table with the number of days, with the cell
66 representing today in active format and background in inactive format.
67
68 If today is before STARTDATE, the left-most cell will be in the
69 3rd format. If today is after ENDDATE the rightmost cell will be
70 in the 3rd format.
71
72 Dates are in this format: YYYY-MM-DD
73
74 By default, each cell is 0.5em wide, unless the table width is
75 specified.
76
77 Debugging
78 Please prepend a '?' to the arguments.
79
80 Examples:
81 [[ProgressBar(60%)]]
82 [[ProgressBar(6/10)]]
83 [[ProgressBar(2005-11-01,2006-01-06)]]
84
85 [[ProgressBar([50%] 60%)]]
86 [[ProgressBar([50px] 60%)]]
87 [[ProgressBar([90%]<#8080ff><#808080> 6/10)]]
88 ----
89 """
90
91
92 # Imports
93 import time, re, StringIO
94 from MoinMoin import version
95 from MoinMoin.parser import wiki
96
97 Dependencies = ["time"] # macro cannot be cached
98
99
100 class _Error (Exception):
101 pass
102
103
104 def escape (str):
105 return str.replace ('&','&').replace ('<', '<').replace ('>', '>')
106
107 def usage (full = False):
108
109 """Returns the interesting part of the module's doc"""
110
111 if full:
112 return __doc__
113 else:
114 rx = re.compile ("--$(.*)^--", re.DOTALL + re.MULTILINE)
115 return rx.findall (__doc__) [0].strip ()
116
117
118 def s2t (s):
119 return time.mktime (time.strptime (s, "%Y-%m-%d"))
120
121
122 def execute (macro, text, args_re=None):
123
124 try: res = _execute (macro, text)
125 except Exception, msg:
126 return """
127 <p><strong class="error">
128 Error: macro ProgressBar: %s</strong> </p>
129 """ % escape ("%s" % msg)
130 return res
131
132
133 def _execute (macro, text):
134
135 fmt = ['#808080','','#8080ff']
136 width ="100px"
137 nopad = False
138
139 res = ""
140 text = text.strip ()
141
142 # help if empty text
143 help = len (text) == 0
144
145 # debug if starts with '?'
146 if text.startswith ('?'):
147 debug = True
148 text = text [1:]
149 else:
150 debug = False
151 orig_text = text
152
153 # Formats
154 try:
155 # Table width
156 if text.startswith ('['):
157 pos = text.rfind (']')
158 width = text [1:pos]
159 text = text [pos+1:].strip ()
160 nopad = True
161
162 # Cells format
163 if text.startswith ('<'):
164 pos = text.rfind ('>')
165 f = text [1:pos].split ('><')
166 text = text [pos+1:].strip ()
167 fmt [:len (f)] = f
168 except:
169 help = True
170
171 # Show help
172 if help:
173 return """
174 <p>
175 <pre>%s</pre></p>
176 """ % escape (usage (0))
177
178 # Cell formatting utility
179 def cell (txt, fmt, nopad=False):
180 if nopad:
181 padding = 'style="padding: 0.25em 1px 0.25em 0px;" '
182 else:
183 padding = 'style="padding: 0.25em 0.25em 0.25em 0.25em;" ' + fmt
184 fmt = padding + fmt
185 if len (txt) == 0:
186 fmt = 'tableheight="0.75em" tablewidth="%s" ' % width + fmt
187 txt = "||"
188 if len (fmt): t = "<%s> ||" % fmt.strip ()
189 else: t = " ||"
190 return txt + t
191
192 # Progress
193 if text.endswith ('%'):
194 for f in fmt [0] + ' %s' % text, fmt [1] :
195 res = cell (res, f, True)
196 if text.startswith ('100'): break
197
198 # Current/Steps
199 elif text.find ('/') > 0:
200 cur, steps = map (int, text.split ('/'))
201 for i in range (steps):
202 res = cell (res, fmt [i>=cur], nopad)
203
204 # Start/end date
205 else:
206 starts, ends = map (lambda s:s.strip (), text.split (","))
207 start, end = s2t (starts), s2t (ends)
208 now = time.mktime (time.localtime ())
209
210 duration = int ( (end-start) / 86400)
211 progress = int ( (now-start) / 86400) -1
212 pcent = int (90 / duration)
213
214 for i in range (duration):
215 if i == 0 and progress < 0:
216 f = fmt [2]
217 elif i == progress:
218 f = fmt [0]
219 else:
220 f = fmt [1]
221 res = cell (res, f, nopad)
222
223 if progress >= duration:
224 res = cell (res, fmt [2], nopad)
225 else:
226 res = cell (res, fmt [1], nopad)
227
228 # Output
229 if debug:
230 res = "{{{[[ProgressBar(%s)]]\n%s}}}\n%s" % (orig_text, res, res)
231 return _format (res, macro.request, macro.formatter)
232
233
234 def _format (src_text, request, formatter):
235 # parse the text (in wiki source format) and make HTML,
236 # after diverting sys.stdout to a string
237 str_out = StringIO.StringIO () # create str to collect output
238 request.redirect (str_out) # divert output to that string
239 # parse this line
240 wiki.Parser (src_text, request).format (formatter)
241 request.redirect () # restore output
242 return str_out.getvalue () # return what was generated
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.