##// END OF EJS Templates
merge with self
Benoit Boissinot -
r1991:a8a618c5 merge default
parent child Browse files
Show More
@@ -0,0 +1,15
1 changeset = '{date|shortdate} {author|person} <{author|email}> ({node|short}{tags})\n\n\t* {files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\n'
2 changeset_quiet = '{date|shortdate} {author|person} <{author|email}>\n\n\t* {desc|firstline|fill68|tabindent|strip}\n\n'
3 changeset_verbose = '{date|isodate} {author|person} <{author|email}> ({node|short}{tags})\n\n\t* {file_adds|stringify|fill68|tabindent}{file_dels|stringify|fill68|tabindent}{files|stringify|fill68|tabindent}{desc|fill68|tabindent|strip}\n\n'
4 start_tags = ' ['
5 tag = '{tag}, '
6 last_tag = '{tag}]'
7 start_files = '('
8 file = '{file}, '
9 last_file = '{file}):\n\t'
10 start_file_adds = '('
11 file_add = '{file_add}, '
12 last_file_add = '{file_add}): new file.\n* '
13 start_file_dels = '('
14 file_del = '{file_del}, '
15 last_file_del = '{file_del}): deleted file.\n* '
@@ -8,7 +8,7
8 8 import re
9 9 from demandload import demandload
10 10 from i18n import gettext as _
11 demandload(globals(), "cStringIO cgi sys os time urllib util")
11 demandload(globals(), "cStringIO cgi re sys os time urllib util textwrap")
12 12
13 13 esctable = {
14 14 '\\': '\\',
@@ -181,8 +181,43 def age(date):
181 181 if n >= 2 or s == 1:
182 182 return fmt(t, n)
183 183
184 def stringify(thing):
185 '''turn nested template iterator into string.'''
186 cs = cStringIO.StringIO()
187 def walk(things):
188 for t in things:
189 if hasattr(t, '__iter__'):
190 walk(t)
191 else:
192 cs.write(t)
193 walk(thing)
194 return cs.getvalue()
195
196 para_re = re.compile('(\n\n|\n\\s*[-*]\\s*)', re.M)
197 space_re = re.compile(r' +')
198
199 def fill(text, width):
200 '''fill many paragraphs.'''
201 def findparas():
202 start = 0
203 while True:
204 m = para_re.search(text, start)
205 if not m:
206 w = len(text)
207 while w > start and text[w-1].isspace(): w -= 1
208 yield text[start:w], text[w:]
209 break
210 yield text[start:m.start(0)], m.group(1)
211 start = m.end(1)
212
213 fp = cStringIO.StringIO()
214 for para, rest in findparas():
215 fp.write(space_re.sub(' ', textwrap.fill(para, width)))
216 fp.write(rest)
217 return fp.getvalue()
218
184 219 def isodate(date):
185 '''turn a (timestamp, tzoff) tuple into an iso 8631 date.'''
220 '''turn a (timestamp, tzoff) tuple into an iso 8631 date and time.'''
186 221 return util.datestr(date, format='%Y-%m-%d %H:%M')
187 222
188 223 def nl2br(text):
@@ -201,25 +236,54 def domain(author):
201 236 if f >= 0: author = author[:f]
202 237 return author
203 238
239 def email(author):
240 '''get email of author.'''
241 r = author.find('>')
242 if r == -1: r = None
243 return author[author.find('<')+1:r]
244
204 245 def person(author):
205 246 '''get name of author, or else username.'''
206 247 f = author.find('<')
207 248 if f == -1: return util.shortuser(author)
208 249 return author[:f].rstrip()
209 250
251 def shortdate(date):
252 '''turn (timestamp, tzoff) tuple into iso 8631 date.'''
253 return util.datestr(date, format='%Y-%m-%d', timezone=False)
254
255 def indent(text, prefix):
256 '''indent each non-empty line of text after first with prefix.'''
257 fp = cStringIO.StringIO()
258 lines = text.splitlines()
259 num_lines = len(lines)
260 for i in xrange(num_lines):
261 l = lines[i]
262 if i and l.strip(): fp.write(prefix)
263 fp.write(l)
264 if i < num_lines - 1 or text.endswith('\n'):
265 fp.write('\n')
266 return fp.getvalue()
267
210 268 common_filters = {
211 269 "addbreaks": nl2br,
212 270 "age": age,
213 271 "date": lambda x: util.datestr(x),
214 272 "domain": domain,
273 "email": email,
215 274 "escape": lambda x: cgi.escape(x, True),
275 "fill68": lambda x: fill(x, width=68),
276 "fill76": lambda x: fill(x, width=76),
216 277 "firstline": lambda x: x.splitlines(1)[0].rstrip('\r\n'),
278 "tabindent": lambda x: indent(x, '\t'),
217 279 "isodate": isodate,
218 280 "obfuscate": obfuscate,
219 281 "permissions": lambda x: x and "-rwxr-xr-x" or "-rw-r--r--",
220 282 "person": person,
221 283 "rfc822date": lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S"),
222 284 "short": lambda x: x[:12],
285 "shortdate": shortdate,
286 "stringify": stringify,
223 287 "strip": lambda x: x.strip(),
224 288 "urlescape": lambda x: urllib.quote(x),
225 289 "user": lambda x: util.shortuser(x),
@@ -8,7 +8,7
8 8 import ConfigParser
9 9 from i18n import gettext as _
10 10 from demandload import *
11 demandload(globals(), "os re socket sys util tempfile")
11 demandload(globals(), "errno os re socket sys tempfile util")
12 12
13 13 class ui(object):
14 14 def __init__(self, verbose=False, debug=False, quiet=False,
@@ -179,9 +179,13 class ui(object):
179 179 sys.stdout.write(str(a))
180 180
181 181 def write_err(self, *args):
182 try:
182 183 if not sys.stdout.closed: sys.stdout.flush()
183 184 for a in args:
184 185 sys.stderr.write(str(a))
186 except IOError, inst:
187 if inst.errno != errno.EPIPE:
188 raise
185 189
186 190 def flush(self):
187 191 try:
@@ -751,15 +751,16 def makedate():
751 751 tz = time.timezone
752 752 return time.mktime(lt), tz
753 753
754 def datestr(date=None, format='%a %b %d %H:%M:%S %Y'):
754 def datestr(date=None, format='%a %b %d %H:%M:%S %Y', timezone=True):
755 755 """represent a (unixtime, offset) tuple as a localized time.
756 756 unixtime is seconds since the epoch, and offset is the time zone's
757 number of seconds away from UTC."""
757 number of seconds away from UTC. if timezone is false, do not
758 append time zone to string."""
758 759 t, tz = date or makedate()
759 return ("%s %+03d%02d" %
760 (time.strftime(format, time.gmtime(float(t) - tz)),
761 -tz / 3600,
762 ((-tz % 3600) / 60)))
760 s = time.strftime(format, time.gmtime(float(t) - tz))
761 if timezone:
762 s += " %+03d%02d" % (-tz / 3600, ((-tz % 3600) / 60))
763 return s
763 764
764 765 def shortuser(user):
765 766 """Return a short representation of a user name or email address."""
General Comments 0
You need to be logged in to leave comments. Login now