##// END OF EJS Templates
hgweb: simplify addition of "(0) navigation entry"
Pierre-Yves David -
r18407:50dc5b24 default
parent child Browse files
Show More
@@ -1,379 +1,378 b''
1 # hgweb/webutil.py - utility library for the web interface.
1 # hgweb/webutil.py - utility library for the web interface.
2 #
2 #
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 import os, copy
9 import os, copy
10 from mercurial import match, patch, scmutil, error, ui, util
10 from mercurial import match, patch, scmutil, error, ui, util
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial.node import hex, nullid
12 from mercurial.node import hex, nullid
13 from common import ErrorResponse
13 from common import ErrorResponse
14 from common import HTTP_NOT_FOUND
14 from common import HTTP_NOT_FOUND
15 import difflib
15 import difflib
16
16
17 def up(p):
17 def up(p):
18 if p[0] != "/":
18 if p[0] != "/":
19 p = "/" + p
19 p = "/" + p
20 if p[-1] == "/":
20 if p[-1] == "/":
21 p = p[:-1]
21 p = p[:-1]
22 up = os.path.dirname(p)
22 up = os.path.dirname(p)
23 if up == "/":
23 if up == "/":
24 return "/"
24 return "/"
25 return up + "/"
25 return up + "/"
26
26
27 def _navseq(step, firststep=None):
27 def _navseq(step, firststep=None):
28 if firststep:
28 if firststep:
29 yield firststep
29 yield firststep
30 if firststep >= 20 and firststep <= 40:
30 if firststep >= 20 and firststep <= 40:
31 firststep = 50
31 firststep = 50
32 yield firststep
32 yield firststep
33 assert step > 0
33 assert step > 0
34 assert firststep > 0
34 assert firststep > 0
35 while step <= firststep:
35 while step <= firststep:
36 step *= 10
36 step *= 10
37 while True:
37 while True:
38 yield 1 * step
38 yield 1 * step
39 yield 3 * step
39 yield 3 * step
40 step *= 10
40 step *= 10
41
41
42 class revnav(object):
42 class revnav(object):
43
43
44 def __init__(self, nodefunc):
44 def __init__(self, nodefunc):
45 """Navigation generation object
45 """Navigation generation object
46
46
47 :nodefun: factory for a changectx from a revision
47 :nodefun: factory for a changectx from a revision
48 """
48 """
49 self.nodefunc = nodefunc
49 self.nodefunc = nodefunc
50
50
51 def __nonzero__(self):
51 def __nonzero__(self):
52 """return True if any revision to navigate over"""
52 """return True if any revision to navigate over"""
53 try:
53 try:
54 self.nodefunc(0)
54 self.nodefunc(0)
55 return True
55 return True
56 except error.RepoError:
56 except error.RepoError:
57 return False
57 return False
58
58
59 def hex(self, rev):
59 def hex(self, rev):
60 return self.nodefunc(rev).hex()
60 return self.nodefunc(rev).hex()
61
61
62 def gen(self, pos, pagelen, limit):
62 def gen(self, pos, pagelen, limit):
63 """computes label and revision id for navigation link
63 """computes label and revision id for navigation link
64
64
65 :pos: is the revision relative to which we generate navigation.
65 :pos: is the revision relative to which we generate navigation.
66 :pagelen: the size of each navigation page
66 :pagelen: the size of each navigation page
67 :limit: how far shall we link
67 :limit: how far shall we link
68
68
69 The return is:
69 The return is:
70 - a single element tuple
70 - a single element tuple
71 - containing a dictionary with a `before` and `after` key
71 - containing a dictionary with a `before` and `after` key
72 - values are generator functions taking arbitrary number of kwargs
72 - values are generator functions taking arbitrary number of kwargs
73 - yield items are dictionaries with `label` and `node` keys
73 - yield items are dictionaries with `label` and `node` keys
74 """
74 """
75 if not self:
75 if not self:
76 # empty repo
76 # empty repo
77 return ({'before': (), 'after': ()},)
77 return ({'before': (), 'after': ()},)
78
78
79 navbefore = []
79 navbefore = [("(0)", self.hex(0))]
80 navafter = []
80 navafter = []
81
81
82 for f in _navseq(1, pagelen):
82 for f in _navseq(1, pagelen):
83 if f > limit:
83 if f > limit:
84 break
84 break
85 if pos + f < limit:
85 if pos + f < limit:
86 navafter.append(("+%d" % f, self.hex(pos + f)))
86 navafter.append(("+%d" % f, self.hex(pos + f)))
87 if pos - f >= 0:
87 if pos - f >= 0:
88 navbefore.insert(0, ("-%d" % f, self.hex(pos - f)))
88 navbefore.insert(0, ("-%d" % f, self.hex(pos - f)))
89
89
90 navafter.append(("tip", "tip"))
90 navafter.append(("tip", "tip"))
91 navbefore.insert(0, ("(0)", self.hex(0)))
92
91
93 data = lambda i: {"label": i[0], "node": i[1]}
92 data = lambda i: {"label": i[0], "node": i[1]}
94 return ({'before': lambda **map: (data(i) for i in navbefore),
93 return ({'before': lambda **map: (data(i) for i in navbefore),
95 'after': lambda **map: (data(i) for i in navafter)},)
94 'after': lambda **map: (data(i) for i in navafter)},)
96
95
97 def _siblings(siblings=[], hiderev=None):
96 def _siblings(siblings=[], hiderev=None):
98 siblings = [s for s in siblings if s.node() != nullid]
97 siblings = [s for s in siblings if s.node() != nullid]
99 if len(siblings) == 1 and siblings[0].rev() == hiderev:
98 if len(siblings) == 1 and siblings[0].rev() == hiderev:
100 return
99 return
101 for s in siblings:
100 for s in siblings:
102 d = {'node': s.hex(), 'rev': s.rev()}
101 d = {'node': s.hex(), 'rev': s.rev()}
103 d['user'] = s.user()
102 d['user'] = s.user()
104 d['date'] = s.date()
103 d['date'] = s.date()
105 d['description'] = s.description()
104 d['description'] = s.description()
106 d['branch'] = s.branch()
105 d['branch'] = s.branch()
107 if util.safehasattr(s, 'path'):
106 if util.safehasattr(s, 'path'):
108 d['file'] = s.path()
107 d['file'] = s.path()
109 yield d
108 yield d
110
109
111 def parents(ctx, hide=None):
110 def parents(ctx, hide=None):
112 return _siblings(ctx.parents(), hide)
111 return _siblings(ctx.parents(), hide)
113
112
114 def children(ctx, hide=None):
113 def children(ctx, hide=None):
115 return _siblings(ctx.children(), hide)
114 return _siblings(ctx.children(), hide)
116
115
117 def renamelink(fctx):
116 def renamelink(fctx):
118 r = fctx.renamed()
117 r = fctx.renamed()
119 if r:
118 if r:
120 return [dict(file=r[0], node=hex(r[1]))]
119 return [dict(file=r[0], node=hex(r[1]))]
121 return []
120 return []
122
121
123 def nodetagsdict(repo, node):
122 def nodetagsdict(repo, node):
124 return [{"name": i} for i in repo.nodetags(node)]
123 return [{"name": i} for i in repo.nodetags(node)]
125
124
126 def nodebookmarksdict(repo, node):
125 def nodebookmarksdict(repo, node):
127 return [{"name": i} for i in repo.nodebookmarks(node)]
126 return [{"name": i} for i in repo.nodebookmarks(node)]
128
127
129 def nodebranchdict(repo, ctx):
128 def nodebranchdict(repo, ctx):
130 branches = []
129 branches = []
131 branch = ctx.branch()
130 branch = ctx.branch()
132 # If this is an empty repo, ctx.node() == nullid,
131 # If this is an empty repo, ctx.node() == nullid,
133 # ctx.branch() == 'default'.
132 # ctx.branch() == 'default'.
134 try:
133 try:
135 branchnode = repo.branchtip(branch)
134 branchnode = repo.branchtip(branch)
136 except error.RepoLookupError:
135 except error.RepoLookupError:
137 branchnode = None
136 branchnode = None
138 if branchnode == ctx.node():
137 if branchnode == ctx.node():
139 branches.append({"name": branch})
138 branches.append({"name": branch})
140 return branches
139 return branches
141
140
142 def nodeinbranch(repo, ctx):
141 def nodeinbranch(repo, ctx):
143 branches = []
142 branches = []
144 branch = ctx.branch()
143 branch = ctx.branch()
145 try:
144 try:
146 branchnode = repo.branchtip(branch)
145 branchnode = repo.branchtip(branch)
147 except error.RepoLookupError:
146 except error.RepoLookupError:
148 branchnode = None
147 branchnode = None
149 if branch != 'default' and branchnode != ctx.node():
148 if branch != 'default' and branchnode != ctx.node():
150 branches.append({"name": branch})
149 branches.append({"name": branch})
151 return branches
150 return branches
152
151
153 def nodebranchnodefault(ctx):
152 def nodebranchnodefault(ctx):
154 branches = []
153 branches = []
155 branch = ctx.branch()
154 branch = ctx.branch()
156 if branch != 'default':
155 if branch != 'default':
157 branches.append({"name": branch})
156 branches.append({"name": branch})
158 return branches
157 return branches
159
158
160 def showtag(repo, tmpl, t1, node=nullid, **args):
159 def showtag(repo, tmpl, t1, node=nullid, **args):
161 for t in repo.nodetags(node):
160 for t in repo.nodetags(node):
162 yield tmpl(t1, tag=t, **args)
161 yield tmpl(t1, tag=t, **args)
163
162
164 def showbookmark(repo, tmpl, t1, node=nullid, **args):
163 def showbookmark(repo, tmpl, t1, node=nullid, **args):
165 for t in repo.nodebookmarks(node):
164 for t in repo.nodebookmarks(node):
166 yield tmpl(t1, bookmark=t, **args)
165 yield tmpl(t1, bookmark=t, **args)
167
166
168 def cleanpath(repo, path):
167 def cleanpath(repo, path):
169 path = path.lstrip('/')
168 path = path.lstrip('/')
170 return scmutil.canonpath(repo.root, '', path)
169 return scmutil.canonpath(repo.root, '', path)
171
170
172 def changeidctx (repo, changeid):
171 def changeidctx (repo, changeid):
173 try:
172 try:
174 ctx = repo[changeid]
173 ctx = repo[changeid]
175 except error.RepoError:
174 except error.RepoError:
176 man = repo.manifest
175 man = repo.manifest
177 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
176 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))]
178
177
179 return ctx
178 return ctx
180
179
181 def changectx (repo, req):
180 def changectx (repo, req):
182 changeid = "tip"
181 changeid = "tip"
183 if 'node' in req.form:
182 if 'node' in req.form:
184 changeid = req.form['node'][0]
183 changeid = req.form['node'][0]
185 ipos=changeid.find(':')
184 ipos=changeid.find(':')
186 if ipos != -1:
185 if ipos != -1:
187 changeid = changeid[(ipos + 1):]
186 changeid = changeid[(ipos + 1):]
188 elif 'manifest' in req.form:
187 elif 'manifest' in req.form:
189 changeid = req.form['manifest'][0]
188 changeid = req.form['manifest'][0]
190
189
191 return changeidctx(repo, changeid)
190 return changeidctx(repo, changeid)
192
191
193 def basechangectx(repo, req):
192 def basechangectx(repo, req):
194 if 'node' in req.form:
193 if 'node' in req.form:
195 changeid = req.form['node'][0]
194 changeid = req.form['node'][0]
196 ipos=changeid.find(':')
195 ipos=changeid.find(':')
197 if ipos != -1:
196 if ipos != -1:
198 changeid = changeid[:ipos]
197 changeid = changeid[:ipos]
199 return changeidctx(repo, changeid)
198 return changeidctx(repo, changeid)
200
199
201 return None
200 return None
202
201
203 def filectx(repo, req):
202 def filectx(repo, req):
204 if 'file' not in req.form:
203 if 'file' not in req.form:
205 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
204 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
206 path = cleanpath(repo, req.form['file'][0])
205 path = cleanpath(repo, req.form['file'][0])
207 if 'node' in req.form:
206 if 'node' in req.form:
208 changeid = req.form['node'][0]
207 changeid = req.form['node'][0]
209 elif 'filenode' in req.form:
208 elif 'filenode' in req.form:
210 changeid = req.form['filenode'][0]
209 changeid = req.form['filenode'][0]
211 else:
210 else:
212 raise ErrorResponse(HTTP_NOT_FOUND, 'node or filenode not given')
211 raise ErrorResponse(HTTP_NOT_FOUND, 'node or filenode not given')
213 try:
212 try:
214 fctx = repo[changeid][path]
213 fctx = repo[changeid][path]
215 except error.RepoError:
214 except error.RepoError:
216 fctx = repo.filectx(path, fileid=changeid)
215 fctx = repo.filectx(path, fileid=changeid)
217
216
218 return fctx
217 return fctx
219
218
220 def listfilediffs(tmpl, files, node, max):
219 def listfilediffs(tmpl, files, node, max):
221 for f in files[:max]:
220 for f in files[:max]:
222 yield tmpl('filedifflink', node=hex(node), file=f)
221 yield tmpl('filedifflink', node=hex(node), file=f)
223 if len(files) > max:
222 if len(files) > max:
224 yield tmpl('fileellipses')
223 yield tmpl('fileellipses')
225
224
226 def diffs(repo, tmpl, ctx, basectx, files, parity, style):
225 def diffs(repo, tmpl, ctx, basectx, files, parity, style):
227
226
228 def countgen():
227 def countgen():
229 start = 1
228 start = 1
230 while True:
229 while True:
231 yield start
230 yield start
232 start += 1
231 start += 1
233
232
234 blockcount = countgen()
233 blockcount = countgen()
235 def prettyprintlines(diff, blockno):
234 def prettyprintlines(diff, blockno):
236 for lineno, l in enumerate(diff.splitlines(True)):
235 for lineno, l in enumerate(diff.splitlines(True)):
237 lineno = "%d.%d" % (blockno, lineno + 1)
236 lineno = "%d.%d" % (blockno, lineno + 1)
238 if l.startswith('+'):
237 if l.startswith('+'):
239 ltype = "difflineplus"
238 ltype = "difflineplus"
240 elif l.startswith('-'):
239 elif l.startswith('-'):
241 ltype = "difflineminus"
240 ltype = "difflineminus"
242 elif l.startswith('@'):
241 elif l.startswith('@'):
243 ltype = "difflineat"
242 ltype = "difflineat"
244 else:
243 else:
245 ltype = "diffline"
244 ltype = "diffline"
246 yield tmpl(ltype,
245 yield tmpl(ltype,
247 line=l,
246 line=l,
248 lineid="l%s" % lineno,
247 lineid="l%s" % lineno,
249 linenumber="% 8s" % lineno)
248 linenumber="% 8s" % lineno)
250
249
251 if files:
250 if files:
252 m = match.exact(repo.root, repo.getcwd(), files)
251 m = match.exact(repo.root, repo.getcwd(), files)
253 else:
252 else:
254 m = match.always(repo.root, repo.getcwd())
253 m = match.always(repo.root, repo.getcwd())
255
254
256 diffopts = patch.diffopts(repo.ui, untrusted=True)
255 diffopts = patch.diffopts(repo.ui, untrusted=True)
257 if basectx is None:
256 if basectx is None:
258 parents = ctx.parents()
257 parents = ctx.parents()
259 node1 = parents and parents[0].node() or nullid
258 node1 = parents and parents[0].node() or nullid
260 else:
259 else:
261 node1 = basectx.node()
260 node1 = basectx.node()
262 node2 = ctx.node()
261 node2 = ctx.node()
263
262
264 block = []
263 block = []
265 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
264 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts):
266 if chunk.startswith('diff') and block:
265 if chunk.startswith('diff') and block:
267 blockno = blockcount.next()
266 blockno = blockcount.next()
268 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
267 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
269 lines=prettyprintlines(''.join(block), blockno))
268 lines=prettyprintlines(''.join(block), blockno))
270 block = []
269 block = []
271 if chunk.startswith('diff') and style != 'raw':
270 if chunk.startswith('diff') and style != 'raw':
272 chunk = ''.join(chunk.splitlines(True)[1:])
271 chunk = ''.join(chunk.splitlines(True)[1:])
273 block.append(chunk)
272 block.append(chunk)
274 blockno = blockcount.next()
273 blockno = blockcount.next()
275 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
274 yield tmpl('diffblock', parity=parity.next(), blockno=blockno,
276 lines=prettyprintlines(''.join(block), blockno))
275 lines=prettyprintlines(''.join(block), blockno))
277
276
278 def compare(tmpl, context, leftlines, rightlines):
277 def compare(tmpl, context, leftlines, rightlines):
279 '''Generator function that provides side-by-side comparison data.'''
278 '''Generator function that provides side-by-side comparison data.'''
280
279
281 def compline(type, leftlineno, leftline, rightlineno, rightline):
280 def compline(type, leftlineno, leftline, rightlineno, rightline):
282 lineid = leftlineno and ("l%s" % leftlineno) or ''
281 lineid = leftlineno and ("l%s" % leftlineno) or ''
283 lineid += rightlineno and ("r%s" % rightlineno) or ''
282 lineid += rightlineno and ("r%s" % rightlineno) or ''
284 return tmpl('comparisonline',
283 return tmpl('comparisonline',
285 type=type,
284 type=type,
286 lineid=lineid,
285 lineid=lineid,
287 leftlinenumber="% 6s" % (leftlineno or ''),
286 leftlinenumber="% 6s" % (leftlineno or ''),
288 leftline=leftline or '',
287 leftline=leftline or '',
289 rightlinenumber="% 6s" % (rightlineno or ''),
288 rightlinenumber="% 6s" % (rightlineno or ''),
290 rightline=rightline or '')
289 rightline=rightline or '')
291
290
292 def getblock(opcodes):
291 def getblock(opcodes):
293 for type, llo, lhi, rlo, rhi in opcodes:
292 for type, llo, lhi, rlo, rhi in opcodes:
294 len1 = lhi - llo
293 len1 = lhi - llo
295 len2 = rhi - rlo
294 len2 = rhi - rlo
296 count = min(len1, len2)
295 count = min(len1, len2)
297 for i in xrange(count):
296 for i in xrange(count):
298 yield compline(type=type,
297 yield compline(type=type,
299 leftlineno=llo + i + 1,
298 leftlineno=llo + i + 1,
300 leftline=leftlines[llo + i],
299 leftline=leftlines[llo + i],
301 rightlineno=rlo + i + 1,
300 rightlineno=rlo + i + 1,
302 rightline=rightlines[rlo + i])
301 rightline=rightlines[rlo + i])
303 if len1 > len2:
302 if len1 > len2:
304 for i in xrange(llo + count, lhi):
303 for i in xrange(llo + count, lhi):
305 yield compline(type=type,
304 yield compline(type=type,
306 leftlineno=i + 1,
305 leftlineno=i + 1,
307 leftline=leftlines[i],
306 leftline=leftlines[i],
308 rightlineno=None,
307 rightlineno=None,
309 rightline=None)
308 rightline=None)
310 elif len2 > len1:
309 elif len2 > len1:
311 for i in xrange(rlo + count, rhi):
310 for i in xrange(rlo + count, rhi):
312 yield compline(type=type,
311 yield compline(type=type,
313 leftlineno=None,
312 leftlineno=None,
314 leftline=None,
313 leftline=None,
315 rightlineno=i + 1,
314 rightlineno=i + 1,
316 rightline=rightlines[i])
315 rightline=rightlines[i])
317
316
318 s = difflib.SequenceMatcher(None, leftlines, rightlines)
317 s = difflib.SequenceMatcher(None, leftlines, rightlines)
319 if context < 0:
318 if context < 0:
320 yield tmpl('comparisonblock', lines=getblock(s.get_opcodes()))
319 yield tmpl('comparisonblock', lines=getblock(s.get_opcodes()))
321 else:
320 else:
322 for oc in s.get_grouped_opcodes(n=context):
321 for oc in s.get_grouped_opcodes(n=context):
323 yield tmpl('comparisonblock', lines=getblock(oc))
322 yield tmpl('comparisonblock', lines=getblock(oc))
324
323
325 def diffstatgen(ctx, basectx):
324 def diffstatgen(ctx, basectx):
326 '''Generator function that provides the diffstat data.'''
325 '''Generator function that provides the diffstat data.'''
327
326
328 stats = patch.diffstatdata(util.iterlines(ctx.diff(basectx)))
327 stats = patch.diffstatdata(util.iterlines(ctx.diff(basectx)))
329 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
328 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats)
330 while True:
329 while True:
331 yield stats, maxname, maxtotal, addtotal, removetotal, binary
330 yield stats, maxname, maxtotal, addtotal, removetotal, binary
332
331
333 def diffsummary(statgen):
332 def diffsummary(statgen):
334 '''Return a short summary of the diff.'''
333 '''Return a short summary of the diff.'''
335
334
336 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
335 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
337 return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
336 return _(' %d files changed, %d insertions(+), %d deletions(-)\n') % (
338 len(stats), addtotal, removetotal)
337 len(stats), addtotal, removetotal)
339
338
340 def diffstat(tmpl, ctx, statgen, parity):
339 def diffstat(tmpl, ctx, statgen, parity):
341 '''Return a diffstat template for each file in the diff.'''
340 '''Return a diffstat template for each file in the diff.'''
342
341
343 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
342 stats, maxname, maxtotal, addtotal, removetotal, binary = statgen.next()
344 files = ctx.files()
343 files = ctx.files()
345
344
346 def pct(i):
345 def pct(i):
347 if maxtotal == 0:
346 if maxtotal == 0:
348 return 0
347 return 0
349 return (float(i) / maxtotal) * 100
348 return (float(i) / maxtotal) * 100
350
349
351 fileno = 0
350 fileno = 0
352 for filename, adds, removes, isbinary in stats:
351 for filename, adds, removes, isbinary in stats:
353 template = filename in files and 'diffstatlink' or 'diffstatnolink'
352 template = filename in files and 'diffstatlink' or 'diffstatnolink'
354 total = adds + removes
353 total = adds + removes
355 fileno += 1
354 fileno += 1
356 yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
355 yield tmpl(template, node=ctx.hex(), file=filename, fileno=fileno,
357 total=total, addpct=pct(adds), removepct=pct(removes),
356 total=total, addpct=pct(adds), removepct=pct(removes),
358 parity=parity.next())
357 parity=parity.next())
359
358
360 class sessionvars(object):
359 class sessionvars(object):
361 def __init__(self, vars, start='?'):
360 def __init__(self, vars, start='?'):
362 self.start = start
361 self.start = start
363 self.vars = vars
362 self.vars = vars
364 def __getitem__(self, key):
363 def __getitem__(self, key):
365 return self.vars[key]
364 return self.vars[key]
366 def __setitem__(self, key, value):
365 def __setitem__(self, key, value):
367 self.vars[key] = value
366 self.vars[key] = value
368 def __copy__(self):
367 def __copy__(self):
369 return sessionvars(copy.copy(self.vars), self.start)
368 return sessionvars(copy.copy(self.vars), self.start)
370 def __iter__(self):
369 def __iter__(self):
371 separator = self.start
370 separator = self.start
372 for key, value in sorted(self.vars.iteritems()):
371 for key, value in sorted(self.vars.iteritems()):
373 yield {'name': key, 'value': str(value), 'separator': separator}
372 yield {'name': key, 'value': str(value), 'separator': separator}
374 separator = '&'
373 separator = '&'
375
374
376 class wsgiui(ui.ui):
375 class wsgiui(ui.ui):
377 # default termwidth breaks under mod_wsgi
376 # default termwidth breaks under mod_wsgi
378 def termwidth(self):
377 def termwidth(self):
379 return 80
378 return 80
General Comments 0
You need to be logged in to leave comments. Login now