##// END OF EJS Templates
Bugfix for empty diff
marcink -
r349:031152a5 default
parent child Browse files
Show More
@@ -1,196 +1,198 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # files controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20 """
21 21 Created on April 21, 2010
22 22 files controller for pylons
23 23 @author: marcink
24 24 """
25 25 from mercurial import archival
26 26 from pylons import request, response, session, tmpl_context as c, url
27 27 from pylons.controllers.util import redirect
28 28 from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
29 29 from pylons_app.lib.base import BaseController, render
30 30 from pylons_app.lib.utils import EmptyChangeset, get_repo_slug
31 31 from pylons_app.model.hg_model import HgModel
32 32 from vcs.exceptions import RepositoryError, ChangesetError
33 33 from vcs.nodes import FileNode
34 34 from vcs.utils import diffs as differ
35 35 import logging
36 36 import pylons_app.lib.helpers as h
37 37 import tempfile
38 38
39 39 log = logging.getLogger(__name__)
40 40
41 41 class FilesController(BaseController):
42 42
43 43 @LoginRequired()
44 44 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
45 45 'repository.admin')
46 46 def __before__(self):
47 47 super(FilesController, self).__before__()
48 48
49 49 def index(self, repo_name, revision, f_path):
50 50 hg_model = HgModel()
51 51 c.repo = repo = hg_model.get_repo(c.repo_name)
52 52 revision = request.POST.get('at_rev', None) or revision
53 53
54 54 def get_next_rev(cur):
55 55 max_rev = len(c.repo.revisions) - 1
56 56 r = cur + 1
57 57 if r > max_rev:
58 58 r = max_rev
59 59 return r
60 60
61 61 def get_prev_rev(cur):
62 62 r = cur - 1
63 63 return r
64 64
65 65 c.f_path = f_path
66 66
67 67
68 68 try:
69 69 cur_rev = repo.get_changeset(revision).revision
70 70 prev_rev = repo.get_changeset(get_prev_rev(cur_rev)).raw_id
71 71 next_rev = repo.get_changeset(get_next_rev(cur_rev)).raw_id
72 72
73 73 c.url_prev = url('files_home', repo_name=c.repo_name,
74 74 revision=prev_rev, f_path=f_path)
75 75 c.url_next = url('files_home', repo_name=c.repo_name,
76 76 revision=next_rev, f_path=f_path)
77 77
78 78 c.changeset = repo.get_changeset(revision)
79 79
80 80
81 81 c.cur_rev = c.changeset.raw_id
82 82 c.rev_nr = c.changeset.revision
83 83 c.files_list = c.changeset.get_node(f_path)
84 84 c.file_history = self._get_history(repo, c.files_list, f_path)
85 85
86 86 except (RepositoryError, ChangesetError):
87 87 c.files_list = None
88 88
89 89 return render('files/files.html')
90 90
91 91 def rawfile(self, repo_name, revision, f_path):
92 92 hg_model = HgModel()
93 93 c.repo = hg_model.get_repo(c.repo_name)
94 94 file_node = c.repo.get_changeset(revision).get_node(f_path)
95 95 response.content_type = file_node.mimetype
96 96 response.content_disposition = 'attachment; filename=%s' \
97 97 % f_path.split('/')[-1]
98 98 return file_node.content
99 99
100 100 def annotate(self, repo_name, revision, f_path):
101 101 hg_model = HgModel()
102 102 c.repo = hg_model.get_repo(c.repo_name)
103 103 cs = c.repo.get_changeset(revision)
104 104 c.file = cs.get_node(f_path)
105 105 c.file_msg = cs.get_file_message(f_path)
106 106 c.cur_rev = cs.raw_id
107 107 c.f_path = f_path
108 108
109 109 return render('files/files_annotate.html')
110 110
111 111 def archivefile(self, repo_name, revision, fileformat):
112 112 archive_specs = {
113 113 '.tar.bz2': ('application/x-tar', 'tbz2'),
114 114 '.tar.gz': ('application/x-tar', 'tgz'),
115 115 '.zip': ('application/zip', 'zip'),
116 116 }
117 117 if not archive_specs.has_key(fileformat):
118 118 return 'Unknown archive type %s' % fileformat
119 119
120 120 def read_in_chunks(file_object, chunk_size=1024 * 40):
121 121 """Lazy function (generator) to read a file piece by piece.
122 122 Default chunk size: 40k."""
123 123 while True:
124 124 data = file_object.read(chunk_size)
125 125 if not data:
126 126 break
127 127 yield data
128 128
129 129 archive = tempfile.TemporaryFile()
130 130 repo = HgModel().get_repo(repo_name).repo
131 131 fname = '%s-%s%s' % (repo_name, revision, fileformat)
132 132 archival.archive(repo, archive, revision, archive_specs[fileformat][1],
133 133 prefix='%s-%s' % (repo_name, revision))
134 134 response.content_type = archive_specs[fileformat][0]
135 135 response.content_disposition = 'attachment; filename=%s' % fname
136 136 archive.seek(0)
137 137 return read_in_chunks(archive)
138 138
139 139 def diff(self, repo_name, f_path):
140 140 hg_model = HgModel()
141 141 diff1 = request.GET.get('diff1')
142 142 diff2 = request.GET.get('diff2')
143 143 c.action = request.GET.get('diff')
144 144 c.no_changes = diff1 == diff2
145 145 c.f_path = f_path
146 146 c.repo = hg_model.get_repo(c.repo_name)
147 147
148 148 try:
149 149 if diff1 not in ['', None, 'None', '0' * 12]:
150 150 c.changeset_1 = c.repo.get_changeset(diff1)
151 151 node1 = c.changeset_1.get_node(f_path)
152 152 else:
153 153 c.changeset_1 = EmptyChangeset()
154 154 node1 = FileNode('.', '')
155 155 if diff2 not in ['', None, 'None', '0' * 12]:
156 156 c.changeset_2 = c.repo.get_changeset(diff2)
157 157 node2 = c.changeset_2.get_node(f_path)
158 158 else:
159 159 c.changeset_2 = EmptyChangeset()
160 160 node2 = FileNode('.', '')
161 161 except RepositoryError:
162 162 return redirect(url('files_home',
163 163 repo_name=c.repo_name, f_path=f_path))
164 164
165 165 c.diff1 = 'r%s:%s' % (c.changeset_1.revision, c.changeset_1.raw_id)
166 166 c.diff2 = 'r%s:%s' % (c.changeset_2.revision, c.changeset_2.raw_id)
167 167 f_udiff = differ.get_udiff(node1, node2)
168 168
169 169 diff = differ.DiffProcessor(f_udiff)
170 170
171 171 if c.action == 'download':
172 172 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
173 173 response.content_type = 'text/plain'
174 174 response.content_disposition = 'attachment; filename=%s' \
175 175 % diff_name
176 176 return diff.raw_diff()
177 177
178 178 elif c.action == 'raw':
179 179 c.cur_diff = '<pre class="raw">%s</pre>' % h.escape(diff.raw_diff())
180 180 elif c.action == 'diff':
181 181 c.cur_diff = diff.as_html()
182 182 else:
183 183 #default option
184 184 c.cur_diff = diff.as_html()
185
186 if not c.cur_diff: c.no_changes = True
185 187 return render('files/file_diff.html')
186 188
187 189 def _get_history(self, repo, node, f_path):
188 190 from vcs.nodes import NodeKind
189 191 if not node.kind is NodeKind.FILE:
190 192 return []
191 193 changesets = node.history
192 194 hist_l = []
193 195 for chs in changesets:
194 196 n_desc = 'r%s:%s' % (chs.revision, chs._short)
195 197 hist_l.append((chs._short, n_desc,))
196 198 return hist_l
General Comments 0
You need to be logged in to leave comments. Login now