~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/util.py

  • Committer: Martin Albisetti
  • Date: 2008-08-20 22:34:59 UTC
  • mto: This revision was merged to the branch mainline in revision 218.
  • Revision ID: argentina@gmail.com-20080820223459-bes0lppswufhtr5g
Added to NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
 
2
# Copyright (C) 2008  Canonical Ltd.
 
3
#                     (Authored by Martin Albisetti <argentina@gmail.com)
2
4
# Copyright (C) 2006  Robey Pointer <robey@lag.net>
3
5
# Copyright (C) 2006  Goffredo Baroncelli <kreijack@inwind.it>
4
6
#
27
29
import datetime
28
30
import logging
29
31
import re
30
 
import sha
31
32
import struct
32
 
import sys
33
33
import threading
34
34
import time
35
 
import traceback
36
 
 
 
35
import types
37
36
 
38
37
log = logging.getLogger("loggerhead.controllers")
39
38
 
60
59
 
61
60
 
62
61
def date_time(value):
63
 
    return value.strftime('%Y-%m-%d %T')
 
62
    if value is not None:
 
63
        return value.strftime('%Y-%m-%d %T')
 
64
    else:
 
65
        return 'N/A'
64
66
 
65
67
 
66
68
def _displaydate(date):
142
144
        return out
143
145
 
144
146
 
145
 
def clean_revid(revid):
146
 
    if revid == 'missing':
147
 
        return revid
148
 
    return sha.new(revid).hexdigest()
149
 
 
150
 
 
151
 
def obfuscate(text):
152
 
    return ''.join([ '&#%d;' % ord(c) for c in text ])
153
 
 
154
 
 
155
147
def trunc(text, limit=10):
156
148
    if len(text) <= limit:
157
149
        return text
158
150
    return text[:limit] + '...'
159
151
 
160
152
 
161
 
def to_utf8(s):
162
 
    if isinstance(s, unicode):
163
 
        return s.encode('utf-8')
164
 
    return s
165
 
 
166
 
 
167
153
STANDARD_PATTERN = re.compile(r'^(.*?)\s*<(.*?)>\s*$')
168
154
EMAIL_PATTERN = re.compile(r'[-\w\d\+_!%\.]+@[-\w\d\+_!%\.]+')
169
155
 
187
173
    return '%s at %s' % (username, domains[0])
188
174
 
189
175
 
190
 
def triple_factors(min_value=1):
191
 
    factors = (1, 3)
192
 
    index = 0
193
 
    n = 1
194
 
    while True:
195
 
        if n >= min_value:
196
 
            yield n * factors[index]
197
 
        index += 1
198
 
        if index >= len(factors):
199
 
            index = 0
200
 
            n *= 10
201
 
 
202
 
 
203
 
def scan_range(pos, max, pagesize=1):
204
 
    """
205
 
    given a position in a maximum range, return a list of negative and positive
206
 
    jump factors for an hgweb-style triple-factor geometric scan.
207
 
 
208
 
    for example, with pos=20 and max=500, the range would be:
209
 
    [ -10, -3, -1, 1, 3, 10, 30, 100, 300 ]
210
 
 
211
 
    i admit this is a very strange way of jumping through revisions.  i didn't
212
 
    invent it. :)
213
 
    """
214
 
    out = []
215
 
    for n in triple_factors(pagesize + 1):
216
 
        if n > max:
217
 
            return out
218
 
        if pos + n < max:
219
 
            out.append(n)
220
 
        if pos - n >= 0:
221
 
            out.insert(0, -n)
222
 
 
223
 
 
224
176
# only do this if unicode turns out to be a problem
225
177
#_BADCHARS_RE = re.compile(ur'[\u007f-\uffff]')
226
178
 
235
187
    s = s.replace(' ', '&nbsp;')
236
188
    return s
237
189
 
238
 
 
239
 
 
240
190
NONBREAKING_SPACE = u'\N{NO-BREAK SPACE}'
241
191
 
 
192
def fill_div(s):
 
193
    """
 
194
    CSS is stupid. In some cases we need to replace an empty value with
 
195
    a non breaking space (&nbsp;). There has to be a better way of doing this.
 
196
 
 
197
    return: the same value recieved if not empty, and a '&nbsp;' if it is.
 
198
    """
 
199
    
 
200
 
 
201
    if s is None:
 
202
        return '&nbsp;'
 
203
    elif isinstance(s, int):
 
204
        return s
 
205
    elif not s.strip():
 
206
        return '&nbsp;'
 
207
    else:
 
208
        try:
 
209
            s = s.decode('utf-8')
 
210
        except UnicodeDecodeError:
 
211
            s = s.decode('iso-8859-15')
 
212
        return s
 
213
 
 
214
 
242
215
def fixed_width(s):
243
216
    """
244
217
    expand tabs and turn spaces into "non-breaking spaces", so browsers won't
266
239
    return '-rw-r--r--'
267
240
 
268
241
 
269
 
def if_present(format, value):
270
 
    """
271
 
    format a value using a format string, if the value exists and is not None.
272
 
    """
273
 
    if value is None:
274
 
        return ''
275
 
    return format % value
276
 
 
277
 
 
278
242
def b64(s):
279
243
    s = base64.encodestring(s).replace('\n', '')
280
244
    while (len(s) > 0) and (s[-1] == '='):
354
318
            return None
355
319
        return navigation.revid_list[navigation.position + offset]
356
320
 
 
321
    navigation.last_in_page_revid = get_offset(navigation.pagesize - 1)
357
322
    navigation.prev_page_revid = get_offset(-1 * navigation.pagesize)
358
323
    navigation.next_page_revid = get_offset(1 * navigation.pagesize)
359
 
    prev_page_revno = navigation.branch.history.get_revno(
 
324
    prev_page_revno = navigation.history.get_revno(
360
325
            navigation.prev_page_revid)
361
 
    next_page_revno = navigation.branch.history.get_revno(
 
326
    next_page_revno = navigation.history.get_revno(
362
327
            navigation.next_page_revid)
363
 
    start_revno = navigation.branch._history.get_revno(navigation.start_revid)
 
328
    start_revno = navigation.history.get_revno(navigation.start_revid)
364
329
 
365
330
    params = { 'filter_file_id': navigation.filter_file_id }
366
331
    if getattr(navigation, 'query', None) is not None:
377
342
            [navigation.scan_url, next_page_revno], **params)
378
343
 
379
344
 
380
 
def log_exception(log):
381
 
    for line in ''.join(traceback.format_exception(*sys.exc_info())).split('\n'):
382
 
        log.debug(line)
383
 
 
384
 
 
385
345
def decorator(unbound):
386
346
    def new_decorator(f):
387
347
        g = unbound(f)
412
372
 
413
373
 
414
374
@decorator
415
 
def strip_whitespace(f):
416
 
    def _f(*a, **kw):
417
 
        out = f(*a, **kw)
418
 
        orig_len = len(out)
419
 
        out = re.sub(r'\n\s+', '\n', out)
420
 
        out = re.sub(r'[ \t]+', ' ', out)
421
 
        out = re.sub(r'\s+\n', '\n', out)
422
 
        new_len = len(out)
423
 
        log.debug('Saved %sB (%d%%) by stripping whitespace.',
424
 
                  human_size(orig_len - new_len),
425
 
                  round(100.0 - float(new_len) * 100.0 / float(orig_len)))
426
 
        return out
427
 
    return _f
428
 
 
429
 
 
430
 
@decorator
431
375
def lsprof(f):
432
376
    def _f(*a, **kw):
433
377
        from loggerhead.lsprof import profile