Klaus Demo ~jonashaag/klaus / 6a2c2fc
Refactoring. Also makes turns a few 500s into 404s. Jonas Haag 9 years ago
5 changed file(s) with 68 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
1212 from docutils.writers.html4css1 import Writer
1313
1414 def render_rest(content):
15
1615 # start by h2 and ignore invalid directives and so on (most likely from Sphinx)
1716 settings = {'initial_header_level': '2', 'report_level':'quiet'}
1817 return publish_parts(content,
8989 sha1_sums = check_output(cmd, cwd=os.path.abspath(self.path))
9090 return [self[sha1] for sha1 in sha1_sums.strip().split('\n')]
9191
92 def get_tree(self, commit, path):
93 """ Returns the Git tree object for `path` at `commit`. """
94 tree = self[commit.tree]
95 if path:
96 for directory in path.strip('/').split('/'):
97 if directory:
98 tree = self[tree[directory][1]]
99 return tree
92 def get_blob_or_tree(self, commit, path):
93 """ Returns the Git tree or blob object for `path` at `commit`. """
94 tree_or_blob = self[commit.tree] # Still a tree here but may turn into
95 # a blob somewhere in the loop.
96 for part in path.strip('/').split('/'):
97 if part:
98 if isinstance(tree_or_blob, dulwich.objects.Blob):
99 # Blobs don't have sub-files/folders.
100 raise KeyError
101 tree_or_blob = self[tree_or_blob[part][1]]
102 return tree_or_blob
100103
101104 def commit_diff(self, commit):
102105 from klaus.utils import guess_is_binary, force_unicode
00 <div class=tree>
11 <h2>Tree @<a href="{{ url_for('commit', repo=repo.name, commit_id=commit_id) }}">{{ commit_id|shorten_sha1 }}</a></h2>
22 <ul>
3 {% for _, name, fullpath in tree.dirs %}
3 {% for _, name, fullpath in root_tree.dirs %}
44 <li><a href="{{ url_for('history', repo=repo.name, commit_id=commit_id, path=fullpath) }}" class=dir>{{ name|force_unicode }}</a></li>
55 {% endfor %}
6 {% for _, name, fullpath in tree.files %}
6 {% for _, name, fullpath in root_tree.files %}
77 <li><a href="{{ url_for('blob', repo=repo.name, commit_id=commit_id, path=fullpath) }}">{{ name|force_unicode }}</a></li>
88 {% endfor %}
99 </ul>
189189 return sha1
190190
191191
192 def parent_directory(path):
193 return os.path.split(path)[0]
194
195
192196 def subpaths(path):
193197 """
194198 Yields a `(last part, subpath)` tuple for all possible sub-paths of `path`.
99 from dulwich.objects import Blob
1010
1111 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
1414
1515
1616 def repo_list():
5555 repo = current_app.repo_map[repo]
5656 if commit_id is None:
5757 commit_id = repo.get_default_branch()
58 commit = repo.get_ref_or_commit(commit_id)
58 commit = repo.get_ref_or_commit(commit_id)
5959 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")
6166
6267 self.context = {
6368 'view': self.view_name,
6772 'branches': repo.get_branch_names(exclude=commit_id),
6873 'tags': repo.get_tag_names(),
6974 'path': path,
75 'blob_or_tree': blob_or_tree,
7076 'subpaths': list(subpaths(path)) if path else None,
7177 }
7278
73 def get_tree(self, path):
74 return self.context['repo'].get_tree(self.context['commit'], path)
75
7679
7780 class TreeViewMixin(object):
7881 """
8083 """
8184 def make_context(self, *args):
8285 super(TreeViewMixin, self).make_context(*args)
83 self.context['tree'] = self.listdir()
86 self.context['root_tree'] = self.listdir()
8487
8588 def listdir(self):
8689 """
8790 Returns a list of directories and files in the current path of the
8891 selected commit
8992 """
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 )
9598
9699 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)
99102 if entry.mode & stat.S_IFDIR:
100103 dirs.append((name.lower(), name, entry.path))
101104 else:
103106 files.sort()
104107 dirs.sort()
105108
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)))
108111
109112 return {'dirs' : dirs, 'files' : files}
110113
111114 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
117120
118121
119122 class HistoryView(TreeViewMixin, BaseRepoView):
144147 def make_context(self, *args):
145148 super(BlobViewMixin, self).make_context(*args)
146149 self.context['filename'] = os.path.basename(self.context['path'])
147 self.context['blob'] = self.get_tree(self.context['path'])
148150
149151
150152 class BlobView(BlobViewMixin, TreeViewMixin, BaseRepoView):
151153 """ Shows a file rendered using ``pygmentize`` """
152154 def make_context(self, *args):
153155 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 })
168181
169182
170183 class RawView(BlobViewMixin, BaseRepoView):
173186 served through a static file server)
174187 """
175188 def get_response(self):
176 chunks = self.context['blob'].chunked
189 chunks = self.context['blob_or_tree'].chunked
177190
178191 if len(chunks) == 1 and not chunks[0]:
179192 # empty file