25
from paste.httpexceptions import HTTPNotFound, HTTPMovedPermanently
27
from bzrlib import errors
28
from bzrlib.revision import is_null as is_null_rev
25
from cherrypy import InternalError
30
27
from loggerhead import util
31
from loggerhead.controllers import TemplatedBranchView
28
from loggerhead.templatefunctions import templatefunctions
31
log = logging.getLogger("loggerhead.controllers")
37
path = path.rstrip('/')
38
path = urllib.quote(posixpath.dirname(path))
34
while path.endswith('/'):
36
path = posixpath.dirname(path)
42
class InventoryUI(TemplatedBranchView):
44
template_path = 'loggerhead.templates.inventory'
47
def get_filelist(self, inv, path, sort_type, revno_url):
49
return the list of all files (and their attributes) within a given
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.
56
file_id = inv.path2id(path)
60
if dir_ie.kind != 'directory':
61
raise HTTPMovedPermanently(self._branch.context_url(['/view', revno_url, path]))
65
for filename, entry in dir_ie.children.iteritems():
66
revid_set.add(entry.revision)
69
for change in self._history.get_changes(list(revid_set)):
70
change_dict[change.revid] = change
72
for filename, entry in dir_ie.children.iteritems():
74
if entry.kind == 'directory':
77
absolutepath = pathname
79
absolutepath = path + '/' + pathname
80
revid = entry.revision
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)
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)
101
# Always sort directories first.
102
file_list.sort(key=lambda x: x.kind != 'directory')
106
def get_values(self, path, kwargs, headers):
107
history = self._history
108
branch = history._branch
40
class InventoryUI (object):
42
def __init__(self, branch):
47
@util.strip_whitespace
48
@turbogears.expose(html='zpt:loggerhead.templates.inventory')
49
def default(self, *args, **kw):
51
h = self._branch.get_history()
110
revid = self.get_revid()
111
rev_tree = branch.repository.revision_tree(revid)
112
except errors.NoSuchRevision:
115
file_id = kwargs.get('file_id', None)
116
start_revid = kwargs.get('start_revid', None)
117
sort_type = kwargs.get('sort', 'filename')
120
path = path.rstrip('/')
121
file_id = rev_tree.path2id(path)
129
path = rev_tree.id2path(file_id)
130
except errors.NoSuchId:
133
# Are we at the top of the tree
134
if path in ['/', '']:
137
updir = dirname(path)
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():
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)
159
'revno_url': revno_url,
163
'filelist': filelist,
164
'start_revid': start_revid,
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,
175
path = values['path']
176
revid = values['revid']
177
# no navbar for revisions
178
navigation = util.Container()
180
if is_null_rev(revid):
181
branch_breadcrumbs = []
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')
188
'fileview_active': True,
189
'directory_breadcrumbs': directory_breadcrumbs,
190
'branch_breadcrumbs': branch_breadcrumbs,
191
'navigation': navigation,
57
revid = h.fix_revid(args[0])
62
inv = h.get_inventory(revid)
64
self.log.exception('Exception fetching changes')
65
raise InternalError('Could not fetch changes')
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)
71
# no navbar for revisions
72
navigation = util.Container()
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 ])
78
path = inv.id2path(file_id)
79
if not path.startswith('/'):
81
idpath = inv.get_idpath(file_id)
84
updir_file_id = idpath[-2]
91
def url(pathargs, **kw):
92
return self._branch.url(pathargs, **util.get_context(**kw))
95
'branch': self._branch,
102
'updir_file_id': updir_file_id,
103
'filelist': h.get_filelist(inv, file_id, sort_type),
105
'posixpath': posixpath,
106
'navigation': navigation,
108
'start_revid': start_revid,
110
vals.update(templatefunctions)
112
self.log.info('/inventory %r: %r secs' % (revid, time.time() - z))