~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/util.py

[rs=mwhudson][release-critical=Rinchen] update to loggerhead trunk,
        mainly to get the code to not hold branches open the whole time but
        also getting some other improvements

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
import datetime
28
28
import logging
29
29
import re
30
 
import sha
31
30
import struct
32
 
import sys
33
31
import threading
34
32
import time
35
 
import traceback
36
33
 
37
34
 
38
35
log = logging.getLogger("loggerhead.controllers")
142
139
        return out
143
140
 
144
141
 
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
142
def trunc(text, limit=10):
156
143
    if len(text) <= limit:
157
144
        return text
158
145
    return text[:limit] + '...'
159
146
 
160
147
 
161
 
def to_utf8(s):
162
 
    if isinstance(s, unicode):
163
 
        return s.encode('utf-8')
164
 
    return s
165
 
 
166
 
 
167
148
STANDARD_PATTERN = re.compile(r'^(.*?)\s*<(.*?)>\s*$')
168
149
EMAIL_PATTERN = re.compile(r'[-\w\d\+_!%\.]+@[-\w\d\+_!%\.]+')
169
150
 
187
168
    return '%s at %s' % (username, domains[0])
188
169
 
189
170
 
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
171
# only do this if unicode turns out to be a problem
225
172
#_BADCHARS_RE = re.compile(ur'[\u007f-\uffff]')
226
173
 
266
213
    return '-rw-r--r--'
267
214
 
268
215
 
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
216
def b64(s):
279
217
    s = base64.encodestring(s).replace('\n', '')
280
218
    while (len(s) > 0) and (s[-1] == '='):
356
294
 
357
295
    navigation.prev_page_revid = get_offset(-1 * navigation.pagesize)
358
296
    navigation.next_page_revid = get_offset(1 * navigation.pagesize)
359
 
    prev_page_revno = navigation.branch.history.get_revno(
 
297
    prev_page_revno = navigation.history.get_revno(
360
298
            navigation.prev_page_revid)
361
 
    next_page_revno = navigation.branch.history.get_revno(
 
299
    next_page_revno = navigation.history.get_revno(
362
300
            navigation.next_page_revid)
363
 
    start_revno = navigation.branch._history.get_revno(navigation.start_revid)
 
301
    start_revno = navigation.history.get_revno(navigation.start_revid)
364
302
 
365
303
    params = { 'filter_file_id': navigation.filter_file_id }
366
304
    if getattr(navigation, 'query', None) is not None:
377
315
            [navigation.scan_url, next_page_revno], **params)
378
316
 
379
317
 
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
318
def decorator(unbound):
386
319
    def new_decorator(f):
387
320
        g = unbound(f)
412
345
 
413
346
 
414
347
@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
348
def lsprof(f):
432
349
    def _f(*a, **kw):
433
350
        from loggerhead.lsprof import profile