~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/util.py

  • Committer: Michael Hudson
  • Date: 2007-11-19 08:55:10 UTC
  • mto: This revision was merged to the branch mainline in revision 142.
  • Revision ID: michael.hudson@canonical.com-20071119085510-ossv2rsqdcg7ikzh
oops

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
#
19
19
 
20
 
try:
21
 
    from xml.etree import ElementTree as ET
22
 
except ImportError:
23
 
    from elementtree import ElementTree as ET
24
 
 
25
20
import base64
26
21
import cgi
27
22
import datetime
34
29
import time
35
30
import traceback
36
31
 
 
32
import turbogears
 
33
 
37
34
 
38
35
log = logging.getLogger("loggerhead.controllers")
39
36
 
 
37
 
 
38
def timespan(delta):
 
39
    if delta.days > 730:
 
40
        # good grief!
 
41
        return '%d years' % (int(delta.days // 365.25),)
 
42
    if delta.days >= 3:
 
43
        return '%d days' % delta.days
 
44
    seg = []
 
45
    if delta.days > 0:
 
46
        if delta.days == 1:
 
47
            seg.append('1 day')
 
48
        else:
 
49
            seg.append('%d days' % delta.days)
 
50
    hrs = delta.seconds // 3600
 
51
    mins = (delta.seconds % 3600) // 60
 
52
    if hrs > 0:
 
53
        if hrs == 1:
 
54
            seg.append('1 hour')
 
55
        else:
 
56
            seg.append('%d hours' % hrs)
 
57
    if delta.days == 0:
 
58
        if mins > 0:
 
59
            if mins == 1:
 
60
                seg.append('1 minute')
 
61
            else:
 
62
                seg.append('%d minutes' % mins)
 
63
        elif hrs == 0:
 
64
            seg.append('less than a minute')
 
65
    return ', '.join(seg)
 
66
 
 
67
 
 
68
def ago(timestamp):
 
69
    now = datetime.datetime.now()
 
70
    return timespan(now - timestamp) + ' ago'
 
71
 
 
72
 
40
73
def fix_year(year):
41
74
    if year < 70:
42
75
        year += 2000
44
77
        year += 1900
45
78
    return year
46
79
 
47
 
# Display of times.
48
 
 
49
 
# date_day -- just the day
50
 
# date_time -- full date with time
51
 
#
52
 
# displaydate -- for use in sentences
53
 
# approximatedate -- for use in tables
54
 
#
55
 
# displaydate and approximatedate return an elementtree <span> Element
56
 
# with the full date in a tooltip.
57
 
 
58
 
def date_day(value):
59
 
    return value.strftime('%Y-%m-%d')
60
 
 
61
 
 
62
 
def date_time(value):
63
 
    return value.strftime('%Y-%m-%d %T')
64
 
 
65
 
 
66
 
def _displaydate(date):
67
 
    delta = abs(datetime.datetime.now() - date)
68
 
    if delta > datetime.timedelta(1, 0, 0):
69
 
        # far in the past or future, display the date
70
 
        return 'on ' + date_day(date)
71
 
    return _approximatedate(date)
72
 
 
73
 
 
74
 
def _approximatedate(date):
 
80
 
 
81
_g_format = '%Y-%m-%d @ %H:%M'
 
82
 
 
83
def format_date(date):
 
84
    if _g_format == 'fancy':
 
85
        return fancy_format_date(date)
 
86
    return date.strftime(_g_format)
 
87
 
 
88
def fancy_format_date(date):
75
89
    delta = datetime.datetime.now() - date
76
 
    if abs(delta) > datetime.timedelta(1, 0, 0):
77
 
        # far in the past or future, display the date
78
 
        return date_day(date)
79
 
    future = delta < datetime.timedelta(0, 0, 0)
80
 
    delta = abs(delta)
81
 
    days = delta.days
82
 
    hours = delta.seconds / 3600
83
 
    minutes = (delta.seconds - (3600*hours)) / 60
84
 
    seconds = delta.seconds % 60
85
 
    result = ''
86
 
    if future:
87
 
        result += 'in '
88
 
    if days != 0:
89
 
        amount = days
90
 
        unit = 'day'
91
 
    elif hours != 0:
92
 
        amount = hours
93
 
        unit = 'hour'
94
 
    elif minutes != 0:
95
 
        amount = minutes
96
 
        unit = 'minute'
 
90
    if delta.days > 300:
 
91
        return date.strftime('%d %b %Y')
97
92
    else:
98
 
        amount = seconds
99
 
        unit = 'second'
100
 
    if amount != 1:
101
 
        unit += 's'
102
 
    result += '%s %s' % (amount, unit)
103
 
    if not future:
104
 
        result += ' ago'
105
 
        return result
106
 
 
107
 
 
108
 
def _wrap_with_date_time_title(date, formatted_date):
109
 
    elem = ET.Element("span")
110
 
    elem.text = formatted_date
111
 
    elem.set("title", date_time(date))
112
 
    return elem
113
 
 
114
 
 
115
 
def approximatedate(date):
116
 
    #FIXME: Returns an object instead of a string
117
 
    return _wrap_with_date_time_title(date, _approximatedate(date))
118
 
 
119
 
 
120
 
def displaydate(date):
121
 
    return _wrap_with_date_time_title(date, _displaydate(date))
 
93
        return date.strftime('%d %b %H:%M')
 
94
 
 
95
def set_date_format(format):
 
96
    global _g_format
 
97
    _g_format = format
122
98
 
123
99
 
124
100
class Container (object):
131
107
                setattr(self, key, value)
132
108
        for key, value in kw.iteritems():
133
109
            setattr(self, key, value)
134
 
 
 
110
    
135
111
    def __repr__(self):
136
112
        out = '{ '
137
113
        for key, value in self.__dict__.iteritems():
186
162
        return '%s at %s' % (username, domains[-2])
187
163
    return '%s at %s' % (username, domains[0])
188
164
 
189
 
 
 
165
    
190
166
def triple_factors(min_value=1):
191
167
    factors = (1, 3)
192
168
    index = 0
204
180
    """
205
181
    given a position in a maximum range, return a list of negative and positive
206
182
    jump factors for an hgweb-style triple-factor geometric scan.
207
 
 
 
183
    
208
184
    for example, with pos=20 and max=500, the range would be:
209
185
    [ -10, -3, -1, 1, 3, 10, 30, 100, 300 ]
210
 
 
 
186
    
211
187
    i admit this is a very strange way of jumping through revisions.  i didn't
212
188
    invent it. :)
213
189
    """
315
291
        divisor = MEG
316
292
    else:
317
293
        divisor = KILO
318
 
 
 
294
    
319
295
    dot = size % divisor
320
296
    base = size - dot
321
297
    dot = dot * 10 // divisor
323
299
    if dot >= 10:
324
300
        base += 1
325
301
        dot -= 10
326
 
 
 
302
    
327
303
    out = str(base)
328
304
    if (base < 100) and (dot != 0):
329
305
        out += '.%d' % (dot,)
334
310
    elif divisor == GIG:
335
311
        out += 'G'
336
312
    return out
337
 
 
 
313
    
338
314
 
339
315
def fill_in_navigation(navigation):
340
316
    """
348
324
    navigation.count = len(navigation.revid_list)
349
325
    navigation.page_position = navigation.position // navigation.pagesize + 1
350
326
    navigation.page_count = (len(navigation.revid_list) + (navigation.pagesize - 1)) // navigation.pagesize
351
 
 
 
327
    
352
328
    def get_offset(offset):
353
329
        if (navigation.position + offset < 0) or (navigation.position + offset > navigation.count - 1):
354
330
            return None
355
331
        return navigation.revid_list[navigation.position + offset]
356
 
 
 
332
    
357
333
    navigation.prev_page_revid = get_offset(-1 * navigation.pagesize)
358
334
    navigation.next_page_revid = get_offset(1 * navigation.pagesize)
359
 
    prev_page_revno = navigation.branch.history.get_revno(
360
 
            navigation.prev_page_revid)
361
 
    next_page_revno = navigation.branch.history.get_revno(
362
 
            navigation.next_page_revid)
363
 
    start_revno = navigation.branch._history.get_revno(navigation.start_revid)
364
 
 
365
 
    params = { 'filter_file_id': navigation.filter_file_id }
 
335
    
 
336
    params = { 'file_id': navigation.file_id }
366
337
    if getattr(navigation, 'query', None) is not None:
367
338
        params['q'] = navigation.query
368
 
 
369
 
    if getattr(navigation, 'start_revid', None) is not None:
370
 
        params['start_revid'] = start_revno
371
 
 
 
339
    else:
 
340
        params['start_revid'] = navigation.start_revid
 
341
        
372
342
    if navigation.prev_page_revid:
373
 
        navigation.prev_page_url = navigation.branch.context_url(
374
 
            [navigation.scan_url, prev_page_revno], **params)
 
343
        navigation.prev_page_url = navigation.branch.url([ navigation.scan_url, navigation.prev_page_revid ], **get_context(**params))
375
344
    if navigation.next_page_revid:
376
 
        navigation.next_page_url = navigation.branch.context_url(
377
 
            [navigation.scan_url, next_page_revno], **params)
 
345
        navigation.next_page_url = navigation.branch.url([ navigation.scan_url, navigation.next_page_revid ], **get_context(**params))
378
346
 
379
347
 
380
348
def log_exception(log):
453
421
#         current location along the navigation path (while browsing)
454
422
#     - starting revid (start_revid)
455
423
#         the current beginning of navigation (navigation continues back to
456
 
#         the original revision) -- this defines an 'alternate mainline'
457
 
#         when the user navigates into a branch.
 
424
#         the original revision) -- this may not be along the primary revision
 
425
#         path since the user may have navigated into a branch
458
426
#     - file_id
459
 
#         the file being looked at
460
 
#     - filter_file_id
461
427
#         if navigating the revisions that touched a file
462
428
#     - q (query)
463
429
#         if navigating the revisions that matched a search query
474
440
#         for re-ordering an existing page by different sort
475
441
 
476
442
t_context = threading.local()
477
 
_valid = ('start_revid', 'file_id', 'filter_file_id', 'q', 'remember',
478
 
          'compare_revid', 'sort')
 
443
_valid = ('start_revid', 'file_id', 'q', 'remember', 'compare_revid', 'sort')
479
444
 
480
445
 
481
446
def set_context(map):
484
449
 
485
450
def get_context(**overrides):
486
451
    """
487
 
    Soon to be deprecated.
488
 
 
489
 
 
490
452
    return a context map that may be overriden by specific values passed in,
491
453
    but only contains keys from the list of valid context keys.
492
 
 
 
454
    
493
455
    if 'clear' is set, only the 'remember' context value will be added, and
494
456
    all other context will be omitted.
495
457
    """