277
237
given a navigation block (used by the template for the page header), fill
278
238
in useful calculated values.
280
navigation.position = history.get_revid_sequence(navigation.revid_list, navigation.revid)
281
if navigation.position is None:
282
navigation.position = 0
283
navigation.count = len(navigation.revid_list)
240
navigation.position = history.get_revid_sequence(navigation.revlist, navigation.revid)
241
navigation.count = len(navigation.revlist)
284
242
navigation.page_position = navigation.position // navigation.pagesize + 1
285
navigation.page_count = (len(navigation.revid_list) + (navigation.pagesize - 1)) // navigation.pagesize
243
navigation.page_count = (len(navigation.revlist) + (navigation.pagesize - 1)) // navigation.pagesize
287
245
def get_offset(offset):
288
246
if (navigation.position + offset < 0) or (navigation.position + offset > navigation.count - 1):
290
return navigation.revid_list[navigation.position + offset]
248
return navigation.revlist[navigation.position + offset]
292
250
navigation.prev_page_revid = get_offset(-1 * navigation.pagesize)
293
251
navigation.next_page_revid = get_offset(1 * navigation.pagesize)
295
params = { 'file_id': navigation.file_id }
296
if getattr(navigation, 'query', None) is not None:
297
params['q'] = navigation.query
299
params['start_revid'] = navigation.start_revid
301
252
if navigation.prev_page_revid:
302
navigation.prev_page_url = navigation.branch.url([ navigation.scan_url, navigation.prev_page_revid ], **get_context(**params))
253
navigation.prev_page_url = turbogears.url([ navigation.scan_url, navigation.prev_page_revid ], file_id=navigation.file_id, start_revid=navigation.start_revid)
303
254
if navigation.next_page_revid:
304
navigation.next_page_url = navigation.branch.url([ navigation.scan_url, navigation.next_page_revid ], **get_context(**params))
307
def log_exception(log):
308
for line in ''.join(traceback.format_exception(*sys.exc_info())).split('\n'):
312
def decorator(unbound):
313
def new_decorator(f):
315
g.__name__ = f.__name__
316
g.__doc__ = f.__doc__
317
g.__dict__.update(f.__dict__)
319
new_decorator.__name__ = unbound.__name__
320
new_decorator.__doc__ = unbound.__doc__
321
new_decorator.__dict__.update(unbound.__dict__)
325
# common threading-lock decorator
326
def with_lock(lockname, debug_name=None):
327
if debug_name is None:
328
debug_name = lockname
330
def _decorator(unbound):
331
def locked(self, *args, **kw):
332
getattr(self, lockname).acquire()
334
return unbound(self, *args, **kw)
336
getattr(self, lockname).release()
342
def strip_whitespace(f):
346
out = re.sub(r'\n\s+', '\n', out)
347
out = re.sub(r'[ \t]+', ' ', out)
348
out = re.sub(r'\s+\n', '\n', out)
350
log.debug('Saved %sB (%d%%) by stripping whitespace.',
351
human_size(orig_len - new_len),
352
round(100.0 - float(new_len) * 100.0 / float(orig_len)))
360
from loggerhead.lsprof import profile
363
ret, stats = profile(f, *a, **kw)
364
log.debug('Finished profiled %s in %d msec.' % (f.__name__, int((time.time() - z) * 1000)))
368
msec = int(now * 1000) % 1000
369
timestr = time.strftime('%Y%m%d%H%M%S', time.localtime(now)) + ('%03d' % msec)
370
filename = f.__name__ + '-' + timestr + '.lsprof'
371
cPickle.dump(stats, open(filename, 'w'), 2)
376
# just thinking out loud here...
378
# so, when browsing around, there are 5 pieces of context, most optional:
380
# current location along the navigation path (while browsing)
381
# - starting revid (start_revid)
382
# the current beginning of navigation (navigation continues back to
383
# the original revision) -- this may not be along the primary revision
384
# path since the user may have navigated into a branch
386
# if navigating the revisions that touched a file
388
# if navigating the revisions that matched a search query
390
# a previous revision to remember for future comparisons
392
# current revid is given on the url path. the rest are optional components
395
# other transient things can be set:
397
# to compare one revision to another, on /revision only
399
# for re-ordering an existing page by different sort
401
t_context = threading.local()
402
_valid = ('start_revid', 'file_id', 'q', 'remember', 'compare_revid', 'sort')
405
def set_context(map):
406
t_context.map = dict((k, v) for (k, v) in map.iteritems() if k in _valid)
409
def get_context(**overrides):
411
return a context map that may be overriden by specific values passed in,
412
but only contains keys from the list of valid context keys.
414
if 'clear' is set, only the 'remember' context value will be added, and
415
all other context will be omitted.
418
if overrides.get('clear', False):
419
map['remember'] = t_context.map.get('remember', None)
421
map.update(t_context.map)
422
overrides = dict((k, v) for (k, v) in overrides.iteritems() if k in _valid)
423
map.update(overrides)
255
navigation.next_page_url = turbogears.url([ navigation.scan_url, navigation.next_page_revid ], file_id=navigation.file_id, start_revid=navigation.start_revid)
258
# global branch history & cache
261
_history_lock = threading.Lock()
265
from loggerhead.history import History
267
config = get_config()
269
_history_lock.acquire()
271
if (_history is None) or _history.out_of_date():
272
log.debug('Reload branch history...')
273
if _history is not None:
274
_history.dont_use_cache()
275
_history = History.from_folder(config.get('folder'))
276
_history.use_cache(config.get('cachepath'))
279
_history_lock.release()
284
def set_config(config):