~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/inventory_ui.py

quiet simpletal's logging, unicode fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
 
# Copyright (C) 2008  Canonical Ltd.
3
2
# Copyright (C) 2006  Robey Pointer <robey@lag.net>
4
3
# Copyright (C) 2006  Goffredo Baroncelli <kreijack@inwind.it>
5
4
#
20
19
 
21
20
import logging
22
21
import posixpath
23
 
import urllib
24
 
 
25
 
from paste.httpexceptions import HTTPNotFound, HTTPMovedPermanently
26
 
 
27
 
from bzrlib import errors
28
 
from bzrlib.revision import is_null as is_null_rev
 
22
import time
 
23
 
 
24
import turbogears
 
25
from cherrypy import InternalError
29
26
 
30
27
from loggerhead import util
31
 
from loggerhead.controllers import TemplatedBranchView
32
 
 
33
 
 
 
28
from loggerhead.templatefunctions import templatefunctions
 
29
 
 
30
 
 
31
log = logging.getLogger("loggerhead.controllers")
34
32
 
35
33
def dirname(path):
36
 
    if path is not None:
37
 
        path = path.rstrip('/')
38
 
        path = urllib.quote(posixpath.dirname(path))
 
34
    while path.endswith('/'):
 
35
        path = path[:-1]
 
36
    path = posixpath.dirname(path)
39
37
    return path
40
38
 
41
 
 
42
 
class InventoryUI(TemplatedBranchView):
43
 
 
44
 
    template_path = 'loggerhead.templates.inventory'
45
 
    supports_json = True
46
 
 
47
 
    def get_filelist(self, inv, path, sort_type, revno_url):
48
 
        """
49
 
        return the list of all files (and their attributes) within a given
50
 
        path subtree.
51
 
 
52
 
        @param inv: The inventory.
53
 
        @param path: The path of a directory within the inventory.
54
 
        @param sort_type: How to sort the results... XXX.
55
 
        """
56
 
        file_id = inv.path2id(path)
57
 
        dir_ie = inv[file_id]
58
 
        file_list = []
59
 
 
60
 
        if dir_ie.kind != 'directory':
61
 
            raise HTTPMovedPermanently(self._branch.context_url(['/view', revno_url, path]))
62
 
 
63
 
        revid_set = set()
64
 
 
65
 
        for filename, entry in dir_ie.children.iteritems():
66
 
            revid_set.add(entry.revision)
67
 
 
68
 
        change_dict = {}
69
 
        for change in self._history.get_changes(list(revid_set)):
70
 
            change_dict[change.revid] = change
71
 
 
72
 
        for filename, entry in dir_ie.children.iteritems():
73
 
            pathname = filename
74
 
            if entry.kind == 'directory':
75
 
                pathname += '/'
76
 
            if path == '':
77
 
                absolutepath = pathname
78
 
            else:
79
 
                absolutepath = path + '/' + pathname
80
 
            revid = entry.revision
81
 
 
82
 
            # TODO: For the JSON rendering, this inlines the "change" aka
83
 
            # revision information attached to each file. Consider either
84
 
            # pulling this out as a separate changes dict, or possibly just
85
 
            # including the revision id and having a separate request to get
86
 
            # back the revision info.
87
 
            file = util.Container(
88
 
                filename=filename, executable=entry.executable,
89
 
                kind=entry.kind, absolutepath=absolutepath,
90
 
                file_id=entry.file_id, size=entry.text_size, revid=revid,
91
 
                change=change_dict[revid])
92
 
            file_list.append(file)
93
 
 
94
 
        if sort_type == 'filename':
95
 
            file_list.sort(key=lambda x: x.filename.lower()) # case-insensitive
96
 
        elif sort_type == 'size':
97
 
            file_list.sort(key=lambda x: x.size)
98
 
        elif sort_type == 'date':
99
 
            file_list.sort(key=lambda x: x.change.date)
100
 
 
101
 
        # Always sort directories first.
102
 
        file_list.sort(key=lambda x: x.kind != 'directory')
103
 
 
104
 
        return file_list
105
 
 
106
 
    def get_values(self, path, kwargs, headers):
107
 
        history = self._history
108
 
        branch = history._branch
 
39
        
 
40
class InventoryUI (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='zpt:loggerhead.templates.inventory')
 
49
    def default(self, *args, **kw):
 
50
        z = time.time()
 
51
        h = self._branch.get_history()
 
52
        util.set_context(kw)
 
53
 
 
54
        h._branch.lock_read()
109
55
        try:
110
 
            revid = self.get_revid()
111
 
            rev_tree = branch.repository.revision_tree(revid)
112
 
        except errors.NoSuchRevision:
113
 
            raise HTTPNotFound()
114
 
 
115
 
        file_id = kwargs.get('file_id', None)
116
 
        start_revid = kwargs.get('start_revid', None)
117
 
        sort_type = kwargs.get('sort', 'filename')
118
 
 
119
 
        if path is not None:
120
 
            path = path.rstrip('/')
121
 
            file_id = rev_tree.path2id(path)
122
 
            if file_id is None:
123
 
                raise HTTPNotFound()
124
 
        else:
125
 
            if file_id is None:
126
 
                path = ''
127
 
            else:
128
 
                try:
129
 
                    path = rev_tree.id2path(file_id)
130
 
                except errors.NoSuchId:
131
 
                    raise HTTPNotFound()
132
 
 
133
 
        # Are we at the top of the tree
134
 
        if path in ['/', '']:
135
 
            updir = None
136
 
        else:
137
 
            updir = dirname(path)
138
 
 
139
 
        if not is_null_rev(revid):
140
 
            change = history.get_changes([ revid ])[0]
141
 
            # If we're looking at the tip, use head: in the URL instead
142
 
            if revid == branch.last_revision():
143
 
                revno_url = 'head:'
144
 
            else:
145
 
                revno_url = history.get_revno(revid)
146
 
            history.add_branch_nicks(change)
147
 
            filelist = self.get_filelist(rev_tree.inventory, path, sort_type, revno_url)
148
 
 
149
 
        else:
150
 
            start_revid = None
151
 
            change = None
152
 
            path = "/"
153
 
            updir = None
154
 
            revno_url = 'head:'
155
 
            filelist = []
156
 
 
157
 
        return {
158
 
            'revid': revid,
159
 
            'revno_url': revno_url,
160
 
            'change': change,
161
 
            'path': path,
162
 
            'updir': updir,
163
 
            'filelist': filelist,
164
 
            'start_revid': start_revid,
165
 
        }
166
 
 
167
 
    def add_template_values(self, values):
168
 
        super(InventoryUI, self).add_template_values(values)
169
 
        # Directory Breadcrumbs
170
 
        directory_breadcrumbs = util.directory_breadcrumbs(
171
 
                self._branch.friendly_name,
172
 
                self._branch.is_root,
173
 
                'files')
174
 
 
175
 
        path = values['path']
176
 
        revid = values['revid']
177
 
        # no navbar for revisions
178
 
        navigation = util.Container()
179
 
 
180
 
        if is_null_rev(revid):
181
 
            branch_breadcrumbs = []
182
 
        else:
183
 
            # Create breadcrumb trail for the path within the branch
184
 
            branch = self._history._branch
185
 
            rev_tree = branch.repository.revision_tree(revid)
186
 
            branch_breadcrumbs = util.branch_breadcrumbs(path, rev_tree, 'files')
187
 
        values.update({
188
 
            'fileview_active': True,
189
 
            'directory_breadcrumbs': directory_breadcrumbs,
190
 
            'branch_breadcrumbs': branch_breadcrumbs,
191
 
            'navigation': navigation,
192
 
        })
 
56
            if len(args) > 0:
 
57
                revid = h.fix_revid(args[0])
 
58
            else:
 
59
                revid = h.last_revid
 
60
 
 
61
            try:
 
62
                inv = h.get_inventory(revid)
 
63
            except:
 
64
                self.log.exception('Exception fetching changes')
 
65
                raise InternalError('Could not fetch changes')
 
66
 
 
67
            file_id = kw.get('file_id', inv.root.file_id)
 
68
            start_revid = kw.get('start_revid', None)
 
69
            sort_type = kw.get('sort', None)
 
70
 
 
71
            # no navbar for revisions
 
72
            navigation = util.Container()
 
73
 
 
74
            change = h.get_changes([ revid ])[0]
 
75
            # add parent & merge-point branch-nick info, in case it's useful
 
76
            h.get_branch_nicks([ change ])
 
77
 
 
78
            path = inv.id2path(file_id)
 
79
            if not path.startswith('/'):
 
80
                path = '/' + path
 
81
            idpath = inv.get_idpath(file_id)
 
82
            if len(idpath) > 1:
 
83
                updir = dirname(path)
 
84
                updir_file_id = idpath[-2]
 
85
            else:
 
86
                updir = None
 
87
                updir_file_id = None
 
88
            if updir == '/':
 
89
                updir_file_id = None
 
90
 
 
91
            def url(pathargs, **kw):
 
92
                return self._branch.url(pathargs, **util.get_context(**kw))
 
93
 
 
94
            vals = {
 
95
                'branch': self._branch,
 
96
                'util': util,
 
97
                'revid': revid,
 
98
                'change': change,
 
99
                'file_id': file_id,
 
100
                'path': path,
 
101
                'updir': updir,
 
102
                'updir_file_id': updir_file_id,
 
103
                'filelist': h.get_filelist(inv, file_id, sort_type),
 
104
                'history': h,
 
105
                'posixpath': posixpath,
 
106
                'navigation': navigation,
 
107
                'url': url,
 
108
                'start_revid': start_revid,
 
109
            }
 
110
            vals.update(templatefunctions)
 
111
            h.flush_cache()
 
112
            self.log.info('/inventory %r: %r secs' % (revid, time.time() - z))
 
113
            return vals
 
114
        finally:
 
115
            h._branch.unlock()