##// END OF EJS Templates
fixed small issue made on latest patches
marcink -
r813:e8b5be26 beta
parent child Browse files
Show More
@@ -1,252 +1,253 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.files
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 Files controller for RhodeCode
7 7
8 8 :created_on: Apr 21, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software; you can redistribute it and/or
14 14 # modify it under the terms of the GNU General Public License
15 15 # as published by the Free Software Foundation; version 2
16 16 # of the License or (at your opinion) any later version of the license.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program; if not, write to the Free Software
25 25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 26 # MA 02110-1301, USA.
27 27 import tempfile
28 28 import logging
29 29 import rhodecode.lib.helpers as h
30 30
31 31 from mercurial import archival
32 32
33 33 from pylons import request, response, session, tmpl_context as c, url
34 34 from pylons.i18n.translation import _
35 35 from pylons.controllers.util import redirect
36 36
37 37 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
38 38 from rhodecode.lib.base import BaseController, render
39 39 from rhodecode.lib.utils import EmptyChangeset
40 40 from rhodecode.model.scm import ScmModel
41 41
42 42 from vcs.exceptions import RepositoryError, ChangesetError
43 43 from vcs.nodes import FileNode
44 44 from vcs.utils import diffs as differ
45 45
46 46 log = logging.getLogger(__name__)
47 47
48 48 class FilesController(BaseController):
49 49
50 50 @LoginRequired()
51 51 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
52 52 'repository.admin')
53 53 def __before__(self):
54 54 super(FilesController, self).__before__()
55 c.cut_off_limit = self.cut_off_limit
55 56
56 57 def index(self, repo_name, revision, f_path):
57 58 hg_model = ScmModel()
58 59 c.repo = hg_model.get_repo(c.repo_name)
59 60 revision = request.POST.get('at_rev', None) or revision
60 61
61 62 def get_next_rev(cur):
62 63 max_rev = len(c.repo.revisions) - 1
63 64 r = cur + 1
64 65 if r > max_rev:
65 66 r = max_rev
66 67 return r
67 68
68 69 def get_prev_rev(cur):
69 70 r = cur - 1
70 71 return r
71 72
72 73 c.f_path = f_path
73 74
74 75
75 76 try:
76 77 c.changeset = c.repo.get_changeset(revision)
77 78 cur_rev = c.changeset.revision
78 79 prev_rev = c.repo.get_changeset(get_prev_rev(cur_rev)).raw_id
79 80 next_rev = c.repo.get_changeset(get_next_rev(cur_rev)).raw_id
80 81
81 82 c.url_prev = url('files_home', repo_name=c.repo_name,
82 83 revision=prev_rev, f_path=f_path)
83 84 c.url_next = url('files_home', repo_name=c.repo_name,
84 85 revision=next_rev, f_path=f_path)
85 86
86 87 try:
87 88 c.files_list = c.changeset.get_node(f_path)
88 89 c.file_history = self._get_history(c.repo, c.files_list, f_path)
89 90 except RepositoryError, e:
90 91 h.flash(str(e), category='warning')
91 92 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
92 93
93 94 except RepositoryError, e:
94 95 h.flash(str(e), category='warning')
95 96 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
96 97
97 98
98 99
99 100 return render('files/files.html')
100 101
101 102 def rawfile(self, repo_name, revision, f_path):
102 103 hg_model = ScmModel()
103 104 c.repo = hg_model.get_repo(c.repo_name)
104 105 file_node = c.repo.get_changeset(revision).get_node(f_path)
105 106 response.content_type = file_node.mimetype
106 107 response.content_disposition = 'attachment; filename=%s' \
107 108 % f_path.split('/')[-1]
108 109 return file_node.content
109 110
110 111 def raw(self, repo_name, revision, f_path):
111 112 hg_model = ScmModel()
112 113 c.repo = hg_model.get_repo(c.repo_name)
113 114 file_node = c.repo.get_changeset(revision).get_node(f_path)
114 115 response.content_type = 'text/plain'
115 116
116 117 return file_node.content
117 118
118 119 def annotate(self, repo_name, revision, f_path):
119 120 hg_model = ScmModel()
120 121 c.repo = hg_model.get_repo(c.repo_name)
121 122
122 123 try:
123 124 c.cs = c.repo.get_changeset(revision)
124 125 c.file = c.cs.get_node(f_path)
125 126 except RepositoryError, e:
126 127 h.flash(str(e), category='warning')
127 128 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
128 129
129 130 c.file_history = self._get_history(c.repo, c.file, f_path)
130 131
131 132 c.f_path = f_path
132 133
133 134 return render('files/files_annotate.html')
134 135
135 136 def archivefile(self, repo_name, revision, fileformat):
136 137 archive_specs = {
137 138 '.tar.bz2': ('application/x-tar', 'tbz2'),
138 139 '.tar.gz': ('application/x-tar', 'tgz'),
139 140 '.zip': ('application/zip', 'zip'),
140 141 }
141 142 if not archive_specs.has_key(fileformat):
142 143 return 'Unknown archive type %s' % fileformat
143 144
144 145 def read_in_chunks(file_object, chunk_size=1024 * 40):
145 146 """Lazy function (generator) to read a file piece by piece.
146 147 Default chunk size: 40k."""
147 148 while True:
148 149 data = file_object.read(chunk_size)
149 150 if not data:
150 151 break
151 152 yield data
152 153
153 154 archive = tempfile.TemporaryFile()
154 155 repo = ScmModel().get_repo(repo_name).repo
155 156 fname = '%s-%s%s' % (repo_name, revision, fileformat)
156 157 archival.archive(repo, archive, revision, archive_specs[fileformat][1],
157 158 prefix='%s-%s' % (repo_name, revision))
158 159 response.content_type = archive_specs[fileformat][0]
159 160 response.content_disposition = 'attachment; filename=%s' % fname
160 161 archive.seek(0)
161 162 return read_in_chunks(archive)
162 163
163 164 def diff(self, repo_name, f_path):
164 165 hg_model = ScmModel()
165 166 diff1 = request.GET.get('diff1')
166 167 diff2 = request.GET.get('diff2')
167 168 c.action = request.GET.get('diff')
168 169 c.no_changes = diff1 == diff2
169 170 c.f_path = f_path
170 171 c.repo = hg_model.get_repo(c.repo_name)
171 172
172 173 try:
173 174 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
174 175 c.changeset_1 = c.repo.get_changeset(diff1)
175 176 node1 = c.changeset_1.get_node(f_path)
176 177 else:
177 178 c.changeset_1 = EmptyChangeset()
178 179 node1 = FileNode('.', '', changeset=c.changeset_1)
179 180
180 181 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
181 182 c.changeset_2 = c.repo.get_changeset(diff2)
182 183 node2 = c.changeset_2.get_node(f_path)
183 184 else:
184 185 c.changeset_2 = EmptyChangeset()
185 186 node2 = FileNode('.', '', changeset=c.changeset_2)
186 187 except RepositoryError:
187 188 return redirect(url('files_home',
188 189 repo_name=c.repo_name, f_path=f_path))
189 190
190 191 f_udiff = differ.get_udiff(node1, node2)
191 192 diff = differ.DiffProcessor(f_udiff)
192 193
193 194 if c.action == 'download':
194 195 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
195 196 response.content_type = 'text/plain'
196 197 response.content_disposition = 'attachment; filename=%s' \
197 198 % diff_name
198 199 return diff.raw_diff()
199 200
200 201 elif c.action == 'raw':
201 202 response.content_type = 'text/plain'
202 203 return diff.raw_diff()
203 204
204 205 elif c.action == 'diff':
205 206 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
206 207 c.cur_diff = _('Diff is to big to display')
207 208 else:
208 209 c.cur_diff = diff.as_html()
209 210 else:
210 211 #default option
211 212 if node1.size > self.cut_off_limit or node2.size > self.cut_off_limit:
212 213 c.cur_diff = _('Diff is to big to display')
213 214 else:
214 215 c.cur_diff = diff.as_html()
215 216
216 217 if not c.cur_diff: c.no_changes = True
217 218 return render('files/file_diff.html')
218 219
219 220 def _get_history(self, repo, node, f_path):
220 221 from vcs.nodes import NodeKind
221 222 if not node.kind is NodeKind.FILE:
222 223 return []
223 224 changesets = node.history
224 225 hist_l = []
225 226
226 227 changesets_group = ([], _("Changesets"))
227 228 branches_group = ([], _("Branches"))
228 229 tags_group = ([], _("Tags"))
229 230
230 231 for chs in changesets:
231 232 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
232 233 changesets_group[0].append((chs.raw_id, n_desc,))
233 234
234 235 hist_l.append(changesets_group)
235 236
236 237 for name, chs in c.repository_branches.items():
237 238 #chs = chs.split(':')[-1]
238 239 branches_group[0].append((chs, name),)
239 240 hist_l.append(branches_group)
240 241
241 242 for name, chs in c.repository_tags.items():
242 243 #chs = chs.split(':')[-1]
243 244 tags_group[0].append((chs, name),)
244 245 hist_l.append(tags_group)
245 246
246 247 return hist_l
247 248
248 249 # [
249 250 # ([("u1", "User1"), ("u2", "User2")], "Users"),
250 251 # ([("g1", "Group1"), ("g2", "Group2")], "Groups")
251 252 # ]
252 253
@@ -1,87 +1,87 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${c.repo_name} ${_('File annotate')} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(u'Home',h.url('/'))}
9 9 &raquo;
10 10 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
11 11 &raquo;
12 12 ${_('annotate')} @ R${c.cs.revision}:${h.short_id(c.cs.raw_id)}
13 13 </%def>
14 14
15 15 <%def name="page_nav()">
16 16 ${self.menu('files')}
17 17 </%def>
18 18 <%def name="main()">
19 19 <div class="box">
20 20 <!-- box / title -->
21 21 <div class="title">
22 22 ${self.breadcrumbs()}
23 23 <ul class="links">
24 24 <li>
25 25 <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.cs.branch}</a></span>
26 26 </li>
27 27 </ul>
28 28 </div>
29 29 <div class="table">
30 30 <div id="files_data">
31 31 <h3 class="files_location">${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cs.revision,c.file.path)}</h3>
32 32 <dl class="overview">
33 33 <dt>${_('Revision')}</dt>
34 34 <dd>${h.link_to("r%s:%s" % (c.file.last_changeset.revision,h.short_id(c.file.last_changeset.raw_id)),
35 35 h.url('changeset_home',repo_name=c.repo_name,revision=c.file.last_changeset.raw_id))} </dd>
36 36 <dt>${_('Size')}</dt>
37 37 <dd>${h.format_byte_size(c.file.size,binary=True)}</dd>
38 38 <dt>${_('Mimetype')}</dt>
39 39 <dd>${c.file.mimetype}</dd>
40 40 <dt>${_('Options')}</dt>
41 41 <dd>${h.link_to(_('show source'),
42 42 h.url('files_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))}
43 43 / ${h.link_to(_('show as raw'),
44 44 h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))}
45 45 / ${h.link_to(_('download as raw'),
46 46 h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.cs.raw_id,f_path=c.f_path))}
47 47 </dd>
48 48 <dt>${_('History')}</dt>
49 49 <dd>
50 50 <div>
51 51 ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')}
52 52 ${h.hidden('diff2',c.file.last_changeset.raw_id)}
53 53 ${h.select('diff1',c.file.last_changeset.raw_id,c.file_history)}
54 54 ${h.submit('diff','diff to revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
55 55 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
56 56 ${h.end_form()}
57 57 </div>
58 58 </dd>
59 59 </dl>
60 60 <div id="body" class="codeblock">
61 61 <div class="code-header">
62 62 <div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${h.short_id(c.file.last_changeset.raw_id)}</div>
63 63 <div class="commit">"${c.file.message}"</div>
64 64 </div>
65 65 <div class="code-body">
66 % if c.file.size < c.file_size_limit:
66 % if c.file.size < c.cut_off_limit:
67 67 ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
68 68 %else:
69 69 ${_('File is to big to display')} ${h.link_to(_('show as raw'),
70 70 h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path))}
71 71 %endif
72 72 </div>
73 73 </div>
74 74 <script type="text/javascript">
75 75 YAHOO.util.Event.onDOMReady(function(){
76 76 YAHOO.util.Event.addListener('show_rev','click',function(e){
77 77 YAHOO.util.Event.preventDefault(e);
78 78 var cs = YAHOO.util.Dom.get('diff1').value;
79 79 var url = "${h.url('files_annotate_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
80 80 window.location = url;
81 81 });
82 82 });
83 83 </script>
84 84 </div>
85 85 </div>
86 86 </div>
87 87 </%def> No newline at end of file
@@ -1,57 +1,57 b''
1 1 <dl>
2 2 <dt>${_('Revision')}</dt>
3 3 <dd>
4 4 ${h.link_to("r%s:%s" % (c.files_list.last_changeset.revision,h.short_id(c.files_list.last_changeset.raw_id)),
5 5 h.url('changeset_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id))}
6 6 </dd>
7 7 <dt>${_('Size')}</dt>
8 8 <dd>${h.format_byte_size(c.files_list.size,binary=True)}</dd>
9 9 <dt>${_('Mimetype')}</dt>
10 10 <dd>${c.files_list.mimetype}</dd>
11 11 <dt>${_('Options')}</dt>
12 12 <dd>${h.link_to(_('show annotation'),
13 13 h.url('files_annotate_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
14 14 / ${h.link_to(_('show as raw'),
15 15 h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
16 16 / ${h.link_to(_('download as raw'),
17 17 h.url('files_rawfile_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
18 18 </dd>
19 19 <dt>${_('History')}</dt>
20 20 <dd>
21 21 <div>
22 22 ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')}
23 23 ${h.hidden('diff2',c.files_list.last_changeset.raw_id)}
24 24 ${h.select('diff1',c.files_list.last_changeset.raw_id,c.file_history)}
25 25 ${h.submit('diff','diff to revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
26 26 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
27 27 ${h.end_form()}
28 28 </div>
29 29 </dd>
30 30 </dl>
31 31
32 32
33 33 <div id="body" class="codeblock">
34 34 <div class="code-header">
35 35 <div class="revision">${c.files_list.name}@r${c.files_list.last_changeset.revision}:${h.short_id(c.files_list.last_changeset.raw_id)}</div>
36 36 <div class="commit">"${c.files_list.last_changeset.message}"</div>
37 37 </div>
38 38 <div class="code-body">
39 % if c.files_list.size < c.file_size_limit:
39 % if c.files_list.size < c.cut_off_limit:
40 40 ${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
41 41 %else:
42 42 ${_('File is to big to display')} ${h.link_to(_('show as raw'),
43 43 h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
44 44 %endif
45 45 </div>
46 46 </div>
47 47
48 48 <script type="text/javascript">
49 49 YAHOO.util.Event.onDOMReady(function(){
50 50 YAHOO.util.Event.addListener('show_rev','click',function(e){
51 51 YAHOO.util.Event.preventDefault(e);
52 52 var cs = YAHOO.util.Dom.get('diff1').value;
53 53 var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
54 54 window.location = url;
55 55 });
56 56 });
57 57 </script> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now