~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/annotate_ui.py

  • Committer: Matt Nordhoff
  • Date: 2010-02-26 04:37:13 UTC
  • mfrom: (400 trunk)
  • mto: This revision was merged to the branch mainline in revision 401.
  • Revision ID: mnordhoff@mattnordhoff.com-20100226043713-7mw3r6dr9qowutmi
Merge trunk for NEWS

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