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