~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/annotate_ui.py

  • Committer: Michael Hudson
  • Date: 2008-02-28 04:34:51 UTC
  • mto: This revision was merged to the branch mainline in revision 147.
  • Revision ID: michael.hudson@canonical.com-20080228043451-nuyn35437fuphe9y
more prep

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
import logging
20
21
import os
 
22
import posixpath
21
23
import time
22
24
 
23
 
import bzrlib.errors
24
 
import bzrlib.textfile
25
 
 
26
 
from paste.httpexceptions import HTTPBadRequest, HTTPServerError
27
 
 
28
 
from loggerhead.controllers import TemplatedBranchView
29
 
try:
30
 
    from loggerhead.highlight import highlight
31
 
except ImportError:
32
 
    highlight = None
 
25
import turbogears
 
26
from cherrypy import HTTPError
 
27
 
33
28
from loggerhead import util
34
29
 
35
30
 
36
 
class AnnotateUI(TemplatedBranchView):
37
 
 
38
 
    template_path = 'loggerhead.templates.annotate'
39
 
 
40
 
    def annotate_file(self, file_id, revid):
 
31
log = logging.getLogger("loggerhead.controllers")
 
32
 
 
33
def dirname(path):
 
34
    while path.endswith('/'):
 
35
        path = path[:-1]
 
36
    path = posixpath.dirname(path)
 
37
    return path
 
38
 
 
39
        
 
40
class AnnotateUI (object):
 
41
 
 
42
    def __init__(self, branch):
 
43
        # BranchView object
 
44
        self._branch = branch
 
45
        self.log = branch.log
 
46
 
 
47
    @util.strip_whitespace
 
48
    @turbogears.expose(html='loggerhead.templates.annotate')
 
49
    def default(self, *args, **kw):
41
50
        z = time.time()
42
 
        lineno = 1
43
 
        parity = 0
44
 
 
45
 
        file_revid = self._history.get_inventory(revid)[file_id].revision
46
 
        tree = self._history._branch.repository.revision_tree(file_revid)
47
 
 
48
 
        file_name = os.path.basename(self._history.get_path(revid, file_id))
49
 
 
 
51
        h = self._branch.get_history()
 
52
        util.set_context(kw)
 
53
 
 
54
        h._branch.lock_read()
50
55
        try:
51
 
            file_lines = tree.get_file_lines(file_id)
52
 
            bzrlib.textfile.check_text_lines(file_lines)
53
 
        except bzrlib.errors.BinaryFile:
54
 
                # bail out; this isn't displayable text
55
 
                yield util.Container(parity=0, lineno=1, status='same',
56
 
                                     text='(This is a binary file.)',
57
 
                                     change=util.Container())
58
 
        else:
59
 
            if highlight is not None:
60
 
                hl_lines = highlight(file_name, ''.join(file_lines))
61
 
                hl_lines.extend([u''] * (len(file_lines) - len(hl_lines)))
 
56
            if len(args) > 0:
 
57
                revid = h.fix_revid(args[0])
62
58
            else:
63
 
                hl_lines = file_lines
64
 
 
65
 
            change_cache = {}
66
 
 
67
 
            last_line_revid = None
68
 
            for line_revid, text in tree.annotate_iter(file_id):
69
 
                if line_revid == last_line_revid:
70
 
                    # remember which lines have a new revno and which don't
71
 
                    status = 'same'
72
 
                else:
73
 
                    status = 'changed'
74
 
                    parity ^= 1
75
 
                    last_line_revid = line_revid
76
 
                    if line_revid in change_cache:
77
 
                        change = change_cache[line_revid]
78
 
                    else:
79
 
                        change = self._history.get_changes([line_revid])[0]
80
 
                        change_cache[line_revid] = change
81
 
 
82
 
                yield util.Container(
83
 
                    parity=parity, lineno=lineno, status=status,
84
 
                    change=change, text=hl_lines[lineno - 1])
85
 
                lineno += 1
86
 
 
87
 
        self.log.debug('annotate: %r secs' % (time.time() - z))
88
 
 
89
 
    def get_values(self, path, kwargs, headers):
90
 
        history = self._history
91
 
        branch = history._branch
92
 
        revid = self.get_revid()
93
 
        revid = history.fix_revid(revid)
94
 
        file_id = kwargs.get('file_id', None)
95
 
        if (file_id is None) and (path is None):
96
 
            raise HTTPBadRequest('No file_id or filename '
97
 
                                 'provided to annotate')
98
 
 
99
 
        if file_id is None:
100
 
            file_id = history.get_file_id(revid, path)
101
 
 
102
 
        # no navbar for revisions
103
 
        navigation = util.Container()
104
 
 
105
 
        if path is None:
106
 
            path = history.get_path(revid, file_id)
107
 
        filename = os.path.basename(path)
108
 
 
109
 
        change = history.get_changes([ revid ])[0]
110
 
        # If we're looking at the tip, use head: in the URL instead
111
 
        if revid == branch.last_revision():
112
 
            revno_url = 'head:'
113
 
        else:
114
 
            revno_url = history.get_revno(revid)
115
 
 
116
 
        # Directory Breadcrumbs
117
 
        directory_breadcrumbs = (
118
 
            util.directory_breadcrumbs(
119
 
                self._branch.friendly_name,
120
 
                self._branch.is_root,
121
 
                'files'))
122
 
 
123
 
        # Create breadcrumb trail for the path within the branch
124
 
        try:
125
 
            inv = history.get_inventory(revid)
126
 
        except:
127
 
            self.log.exception('Exception fetching changes')
128
 
            raise HTTPServerError('Could not fetch changes')
129
 
        branch_breadcrumbs = util.branch_breadcrumbs(path, inv, 'files')
130
 
 
131
 
        return {
132
 
            'revno_url': revno_url,
133
 
            'file_id': file_id,
134
 
            'path': path,
135
 
            'filename': filename,
136
 
            'navigation': navigation,
137
 
            'change': change,
138
 
            'contents': list(self.annotate_file(file_id, revid)),
139
 
            'fileview_active': True,
140
 
            'directory_breadcrumbs': directory_breadcrumbs,
141
 
            'branch_breadcrumbs': branch_breadcrumbs,
142
 
        }
 
59
                revid = h.last_revid
 
60
 
 
61
            path = None
 
62
            if len(args) > 1:
 
63
                path = '/'.join(args[1:])
 
64
                if not path.startswith('/'):
 
65
                    path = '/' + path
 
66
 
 
67
            file_id = kw.get('file_id', None)
 
68
            if (file_id is None) and (path is None):
 
69
                raise HTTPError(400, 'No file_id or filename provided to annotate')
 
70
 
 
71
            if file_id is None:
 
72
                file_id = h.get_file_id(revid, path)
 
73
 
 
74
            # no navbar for revisions
 
75
            navigation = util.Container()
 
76
 
 
77
            if path is None:
 
78
                path = h.get_path(revid, file_id)
 
79
            filename = os.path.basename(path)
 
80
 
 
81
            vals = {
 
82
                'branch': self._branch,
 
83
                'util': util,
 
84
                'revid': revid,
 
85
                'file_id': file_id,
 
86
                'path': path,
 
87
                'filename': filename,
 
88
                'history': h,
 
89
                'navigation': navigation,
 
90
                'change': h.get_changes([ revid ])[0],
 
91
                'contents': list(h.annotate_file(file_id, revid)),
 
92
            }
 
93
            h.flush_cache()
 
94
            self.log.info('/annotate: %r secs' % (time.time() - z,))
 
95
            return vals
 
96
        finally:
 
97
            h._branch.unlock()