~loggerhead-team/loggerhead/trunk-rich

« back to all changes in this revision

Viewing changes to loggerhead/controllers/inventory_ui.py

[rs=igc] update to lp:loggerhead trunk

Show diffs side-by-side

added added

removed removed

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