9 | 9 |
from dulwich.objects import Blob
|
10 | 10 |
|
11 | 11 |
from klaus import markup
|
12 | |
from klaus.utils import subpaths, get_mimetype_and_encoding, pygmentize, \
|
13 | |
force_unicode, guess_is_binary, guess_is_image
|
|
12 |
from klaus.utils import parent_directory, subpaths, get_mimetype_and_encoding, \
|
|
13 |
pygmentize, force_unicode, guess_is_binary, guess_is_image
|
14 | 14 |
|
15 | 15 |
|
16 | 16 |
def repo_list():
|
|
55 | 55 |
repo = current_app.repo_map[repo]
|
56 | 56 |
if commit_id is None:
|
57 | 57 |
commit_id = repo.get_default_branch()
|
58 | |
commit = repo.get_ref_or_commit(commit_id)
|
|
58 |
commit = repo.get_ref_or_commit(commit_id)
|
59 | 59 |
except KeyError:
|
60 | |
raise NotFound
|
|
60 |
raise NotFound("Commit not found")
|
|
61 |
|
|
62 |
try:
|
|
63 |
blob_or_tree = repo.get_blob_or_tree(commit, path)
|
|
64 |
except KeyError:
|
|
65 |
raise NotFound("File not found")
|
61 | 66 |
|
62 | 67 |
self.context = {
|
63 | 68 |
'view': self.view_name,
|
|
67 | 72 |
'branches': repo.get_branch_names(exclude=commit_id),
|
68 | 73 |
'tags': repo.get_tag_names(),
|
69 | 74 |
'path': path,
|
|
75 |
'blob_or_tree': blob_or_tree,
|
70 | 76 |
'subpaths': list(subpaths(path)) if path else None,
|
71 | 77 |
}
|
72 | 78 |
|
73 | |
def get_tree(self, path):
|
74 | |
return self.context['repo'].get_tree(self.context['commit'], path)
|
75 | |
|
76 | 79 |
|
77 | 80 |
class TreeViewMixin(object):
|
78 | 81 |
"""
|
|
80 | 83 |
"""
|
81 | 84 |
def make_context(self, *args):
|
82 | 85 |
super(TreeViewMixin, self).make_context(*args)
|
83 | |
self.context['tree'] = self.listdir()
|
|
86 |
self.context['root_tree'] = self.listdir()
|
84 | 87 |
|
85 | 88 |
def listdir(self):
|
86 | 89 |
"""
|
87 | 90 |
Returns a list of directories and files in the current path of the
|
88 | 91 |
selected commit
|
89 | 92 |
"""
|
90 | |
try:
|
91 | |
root = self.get_root_directory()
|
92 | |
tree = self.get_tree(root)
|
93 | |
except KeyError:
|
94 | |
raise NotFound
|
|
93 |
root_directory = self.get_root_directory()
|
|
94 |
root_tree = self.context['repo'].get_blob_or_tree(
|
|
95 |
self.context['commit'],
|
|
96 |
root_directory
|
|
97 |
)
|
95 | 98 |
|
96 | 99 |
dirs, files = [], []
|
97 | |
for entry in tree.iteritems():
|
98 | |
name, entry = entry.path, entry.in_path(root)
|
|
100 |
for entry in root_tree.iteritems():
|
|
101 |
name, entry = entry.path, entry.in_path(root_directory)
|
99 | 102 |
if entry.mode & stat.S_IFDIR:
|
100 | 103 |
dirs.append((name.lower(), name, entry.path))
|
101 | 104 |
else:
|
|
103 | 106 |
files.sort()
|
104 | 107 |
dirs.sort()
|
105 | 108 |
|
106 | |
if root:
|
107 | |
dirs.insert(0, (None, '..', os.path.split(root)[0]))
|
|
109 |
if root_directory:
|
|
110 |
dirs.insert(0, (None, '..', parent_directory(root_directory)))
|
108 | 111 |
|
109 | 112 |
return {'dirs' : dirs, 'files' : files}
|
110 | 113 |
|
111 | 114 |
def get_root_directory(self):
|
112 | |
root = self.context['path']
|
113 | |
if isinstance(self.get_tree(root), Blob):
|
114 | |
# 'path' is a file name
|
115 | |
root = os.path.split(self.context['path'])[0]
|
116 | |
return root
|
|
115 |
root_directory = self.context['path']
|
|
116 |
if isinstance(self.context['blob_or_tree'], Blob):
|
|
117 |
# 'path' is a file (not folder) name
|
|
118 |
root_directory = parent_directory(root_directory)
|
|
119 |
return root_directory
|
117 | 120 |
|
118 | 121 |
|
119 | 122 |
class HistoryView(TreeViewMixin, BaseRepoView):
|
|
144 | 147 |
def make_context(self, *args):
|
145 | 148 |
super(BlobViewMixin, self).make_context(*args)
|
146 | 149 |
self.context['filename'] = os.path.basename(self.context['path'])
|
147 | |
self.context['blob'] = self.get_tree(self.context['path'])
|
148 | 150 |
|
149 | 151 |
|
150 | 152 |
class BlobView(BlobViewMixin, TreeViewMixin, BaseRepoView):
|
151 | 153 |
""" Shows a file rendered using ``pygmentize`` """
|
152 | 154 |
def make_context(self, *args):
|
153 | 155 |
super(BlobView, self).make_context(*args)
|
154 | |
render_markup = 'markup' not in request.args
|
155 | |
rendered_code = pygmentize(
|
156 | |
force_unicode(self.context['blob'].data),
|
157 | |
self.context['filename'],
|
158 | |
render_markup
|
159 | |
)
|
160 | |
self.context.update({
|
161 | |
'too_large': sum(map(len, self.context['blob'].chunked)) > 100*1024,
|
162 | |
'is_markup': markup.can_render(self.context['filename']),
|
163 | |
'render_markup': render_markup,
|
164 | |
'rendered_code': rendered_code,
|
165 | |
'is_binary': guess_is_binary(self.context['blob']),
|
166 | |
'is_image': guess_is_image(self.context['filename']),
|
167 | |
})
|
|
156 |
|
|
157 |
if guess_is_binary(self.context['blob_or_tree']):
|
|
158 |
self.context.update({
|
|
159 |
'is_markup': False,
|
|
160 |
'is_binary': True,
|
|
161 |
'is_image': False,
|
|
162 |
})
|
|
163 |
if guess_is_image(self.context['filename']):
|
|
164 |
self.context.update({
|
|
165 |
'is_image': True,
|
|
166 |
})
|
|
167 |
else:
|
|
168 |
render_markup = 'markup' not in request.args
|
|
169 |
rendered_code = pygmentize(
|
|
170 |
force_unicode(self.context['blob_or_tree'].data),
|
|
171 |
self.context['filename'],
|
|
172 |
render_markup
|
|
173 |
)
|
|
174 |
self.context.update({
|
|
175 |
'too_large': sum(map(len, self.context['blob_or_tree'].chunked)) > 100*1024,
|
|
176 |
'is_markup': markup.can_render(self.context['filename']),
|
|
177 |
'render_markup': render_markup,
|
|
178 |
'rendered_code': rendered_code,
|
|
179 |
'is_binary': False,
|
|
180 |
})
|
168 | 181 |
|
169 | 182 |
|
170 | 183 |
class RawView(BlobViewMixin, BaseRepoView):
|
|
173 | 186 |
served through a static file server)
|
174 | 187 |
"""
|
175 | 188 |
def get_response(self):
|
176 | |
chunks = self.context['blob'].chunked
|
|
189 |
chunks = self.context['blob_or_tree'].chunked
|
177 | 190 |
|
178 | 191 |
if len(chunks) == 1 and not chunks[0]:
|
179 | 192 |
# empty file
|