##// END OF EJS Templates
some changes for #45....
marcink -
r644:c8bd0e6c beta
parent child Browse files
Show More
@@ -1,181 +1,183 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # changeset controller for pylons
3 # changeset controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; version 2
7 # as published by the Free Software Foundation; version 2
8 # of the License or (at your opinion) any later version of the license.
8 # of the License or (at your opinion) any later version of the license.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02110-1301, USA.
18 # MA 02110-1301, USA.
19 from rhodecode.lib.utils import EmptyChangeset
19 from rhodecode.lib.utils import EmptyChangeset
20 """
20 """
21 Created on April 25, 2010
21 Created on April 25, 2010
22 changeset controller for pylons
22 changeset controller for pylons
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from pylons import tmpl_context as c, url, request, response
25 from pylons import tmpl_context as c, url, request, response
26 from pylons.i18n.translation import _
26 from pylons.i18n.translation import _
27 from pylons.controllers.util import redirect
27 from pylons.controllers.util import redirect
28 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
28 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
29 from rhodecode.lib.base import BaseController, render
29 from rhodecode.lib.base import BaseController, render
30 import rhodecode.lib.helpers as h
30 from rhodecode.model.hg import HgModel
31 from rhodecode.model.hg import HgModel
31 from vcs.exceptions import RepositoryError, ChangesetError
32 from vcs.exceptions import RepositoryError, ChangesetError
32 from vcs.nodes import FileNode
33 from vcs.nodes import FileNode
33 from vcs.utils import diffs as differ
34 from vcs.utils import diffs as differ
34 import logging
35 import logging
35 import traceback
36 import traceback
36
37
37 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
38
39
39 class ChangesetController(BaseController):
40 class ChangesetController(BaseController):
40
41
41 @LoginRequired()
42 @LoginRequired()
42 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
43 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
43 'repository.admin')
44 'repository.admin')
44 def __before__(self):
45 def __before__(self):
45 super(ChangesetController, self).__before__()
46 super(ChangesetController, self).__before__()
46
47
47 def index(self, revision):
48 def index(self, revision):
48 hg_model = HgModel()
49 hg_model = HgModel()
49 cut_off_limit = 1024 * 250
50 cut_off_limit = 1024 * 250
50
51
51 def wrap_to_table(str):
52 def wrap_to_table(str):
52
53
53 return '''<table class="code-difftable">
54 return '''<table class="code-difftable">
54 <tr class="line">
55 <tr class="line">
55 <td class="lineno new"></td>
56 <td class="lineno new"></td>
56 <td class="code"><pre>%s</pre></td>
57 <td class="code"><pre>%s</pre></td>
57 </tr>
58 </tr>
58 </table>''' % str
59 </table>''' % str
59
60
60 try:
61 try:
61 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
62 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
62 except RepositoryError:
63 except RepositoryError, e:
63 log.error(traceback.format_exc())
64 log.error(traceback.format_exc())
65 h.flash(str(e), category='warning')
64 return redirect(url('home'))
66 return redirect(url('home'))
65 else:
67 else:
66 try:
68 try:
67 c.changeset_old = c.changeset.parents[0]
69 c.changeset_old = c.changeset.parents[0]
68 except IndexError:
70 except IndexError:
69 c.changeset_old = None
71 c.changeset_old = None
70 c.changes = []
72 c.changes = []
71
73
72 #===================================================================
74 #===================================================================
73 # ADDED FILES
75 # ADDED FILES
74 #===================================================================
76 #===================================================================
75 c.sum_added = 0
77 c.sum_added = 0
76 for node in c.changeset.added:
78 for node in c.changeset.added:
77
79
78 filenode_old = FileNode(node.path, '', EmptyChangeset())
80 filenode_old = FileNode(node.path, '', EmptyChangeset())
79 if filenode_old.is_binary or node.is_binary:
81 if filenode_old.is_binary or node.is_binary:
80 diff = wrap_to_table(_('binary file'))
82 diff = wrap_to_table(_('binary file'))
81 else:
83 else:
82 c.sum_added += node.size
84 c.sum_added += node.size
83 if c.sum_added < cut_off_limit:
85 if c.sum_added < cut_off_limit:
84 f_udiff = differ.get_udiff(filenode_old, node)
86 f_udiff = differ.get_udiff(filenode_old, node)
85 diff = differ.DiffProcessor(f_udiff).as_html()
87 diff = differ.DiffProcessor(f_udiff).as_html()
86
88
87 else:
89 else:
88 diff = wrap_to_table(_('Changeset is to big and was cut'
90 diff = wrap_to_table(_('Changeset is to big and was cut'
89 ' off, see raw changeset instead'))
91 ' off, see raw changeset instead'))
90
92
91 cs1 = None
93 cs1 = None
92 cs2 = node.last_changeset.raw_id
94 cs2 = node.last_changeset.raw_id
93 c.changes.append(('added', node, diff, cs1, cs2))
95 c.changes.append(('added', node, diff, cs1, cs2))
94
96
95 #===================================================================
97 #===================================================================
96 # CHANGED FILES
98 # CHANGED FILES
97 #===================================================================
99 #===================================================================
98 c.sum_removed = 0
100 c.sum_removed = 0
99 for node in c.changeset.changed:
101 for node in c.changeset.changed:
100 try:
102 try:
101 filenode_old = c.changeset_old.get_node(node.path)
103 filenode_old = c.changeset_old.get_node(node.path)
102 except ChangesetError:
104 except ChangesetError:
103 filenode_old = FileNode(node.path, '', EmptyChangeset())
105 filenode_old = FileNode(node.path, '', EmptyChangeset())
104
106
105 if filenode_old.is_binary or node.is_binary:
107 if filenode_old.is_binary or node.is_binary:
106 diff = wrap_to_table(_('binary file'))
108 diff = wrap_to_table(_('binary file'))
107 else:
109 else:
108
110
109 if c.sum_removed < cut_off_limit:
111 if c.sum_removed < cut_off_limit:
110 f_udiff = differ.get_udiff(filenode_old, node)
112 f_udiff = differ.get_udiff(filenode_old, node)
111 diff = differ.DiffProcessor(f_udiff).as_html()
113 diff = differ.DiffProcessor(f_udiff).as_html()
112 if diff:
114 if diff:
113 c.sum_removed += len(diff)
115 c.sum_removed += len(diff)
114 else:
116 else:
115 diff = wrap_to_table(_('Changeset is to big and was cut'
117 diff = wrap_to_table(_('Changeset is to big and was cut'
116 ' off, see raw changeset instead'))
118 ' off, see raw changeset instead'))
117
119
118
120
119 cs1 = filenode_old.last_changeset.raw_id
121 cs1 = filenode_old.last_changeset.raw_id
120 cs2 = node.last_changeset.raw_id
122 cs2 = node.last_changeset.raw_id
121 c.changes.append(('changed', node, diff, cs1, cs2))
123 c.changes.append(('changed', node, diff, cs1, cs2))
122
124
123 #===================================================================
125 #===================================================================
124 # REMOVED FILES
126 # REMOVED FILES
125 #===================================================================
127 #===================================================================
126 for node in c.changeset.removed:
128 for node in c.changeset.removed:
127 c.changes.append(('removed', node, None, None, None))
129 c.changes.append(('removed', node, None, None, None))
128
130
129 return render('changeset/changeset.html')
131 return render('changeset/changeset.html')
130
132
131 def raw_changeset(self, revision):
133 def raw_changeset(self, revision):
132
134
133 hg_model = HgModel()
135 hg_model = HgModel()
134 method = request.GET.get('diff', 'show')
136 method = request.GET.get('diff', 'show')
135 try:
137 try:
136 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
138 c.changeset = hg_model.get_repo(c.repo_name).get_changeset(revision)
137 except RepositoryError:
139 except RepositoryError:
138 log.error(traceback.format_exc())
140 log.error(traceback.format_exc())
139 return redirect(url('home'))
141 return redirect(url('home'))
140 else:
142 else:
141 try:
143 try:
142 c.changeset_old = c.changeset.parents[0]
144 c.changeset_old = c.changeset.parents[0]
143 except IndexError:
145 except IndexError:
144 c.changeset_old = None
146 c.changeset_old = None
145 c.changes = []
147 c.changes = []
146
148
147 for node in c.changeset.added:
149 for node in c.changeset.added:
148 filenode_old = FileNode(node.path, '')
150 filenode_old = FileNode(node.path, '')
149 if filenode_old.is_binary or node.is_binary:
151 if filenode_old.is_binary or node.is_binary:
150 diff = _('binary file')
152 diff = _('binary file')
151 else:
153 else:
152 f_udiff = differ.get_udiff(filenode_old, node)
154 f_udiff = differ.get_udiff(filenode_old, node)
153 diff = differ.DiffProcessor(f_udiff).raw_diff()
155 diff = differ.DiffProcessor(f_udiff).raw_diff()
154
156
155 cs1 = None
157 cs1 = None
156 cs2 = node.last_changeset.raw_id
158 cs2 = node.last_changeset.raw_id
157 c.changes.append(('added', node, diff, cs1, cs2))
159 c.changes.append(('added', node, diff, cs1, cs2))
158
160
159 for node in c.changeset.changed:
161 for node in c.changeset.changed:
160 filenode_old = c.changeset_old.get_node(node.path)
162 filenode_old = c.changeset_old.get_node(node.path)
161 if filenode_old.is_binary or node.is_binary:
163 if filenode_old.is_binary or node.is_binary:
162 diff = _('binary file')
164 diff = _('binary file')
163 else:
165 else:
164 f_udiff = differ.get_udiff(filenode_old, node)
166 f_udiff = differ.get_udiff(filenode_old, node)
165 diff = differ.DiffProcessor(f_udiff).raw_diff()
167 diff = differ.DiffProcessor(f_udiff).raw_diff()
166
168
167 cs1 = filenode_old.last_changeset.raw_id
169 cs1 = filenode_old.last_changeset.raw_id
168 cs2 = node.last_changeset.raw_id
170 cs2 = node.last_changeset.raw_id
169 c.changes.append(('changed', node, diff, cs1, cs2))
171 c.changes.append(('changed', node, diff, cs1, cs2))
170
172
171 response.content_type = 'text/plain'
173 response.content_type = 'text/plain'
172 if method == 'download':
174 if method == 'download':
173 response.content_disposition = 'attachment; filename=%s.patch' % revision
175 response.content_disposition = 'attachment; filename=%s.patch' % revision
174 parent = True if len(c.changeset.parents) > 0 else False
176 parent = True if len(c.changeset.parents) > 0 else False
175 c.parent_tmpl = 'Parent %s' % c.changeset.parents[0].raw_id if parent else ''
177 c.parent_tmpl = 'Parent %s' % c.changeset.parents[0].raw_id if parent else ''
176
178
177 c.diffs = ''
179 c.diffs = ''
178 for x in c.changes:
180 for x in c.changes:
179 c.diffs += x[2]
181 c.diffs += x[2]
180
182
181 return render('changeset/raw_changeset.html')
183 return render('changeset/raw_changeset.html')
@@ -1,212 +1,217 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # files controller for pylons
3 # files controller for pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20 """
20 """
21 Created on April 21, 2010
21 Created on April 21, 2010
22 files controller for pylons
22 files controller for pylons
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from mercurial import archival
25 from mercurial import archival
26 from pylons import request, response, session, tmpl_context as c, url
26 from pylons import request, response, session, tmpl_context as c, url
27 from pylons.i18n.translation import _
27 from pylons.i18n.translation import _
28 from pylons.controllers.util import redirect
28 from pylons.controllers.util import redirect
29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
30 from rhodecode.lib.base import BaseController, render
30 from rhodecode.lib.base import BaseController, render
31 from rhodecode.lib.utils import EmptyChangeset
31 from rhodecode.lib.utils import EmptyChangeset
32 from rhodecode.model.hg import HgModel
32 from rhodecode.model.hg import HgModel
33 from vcs.exceptions import RepositoryError, ChangesetError
33 from vcs.exceptions import RepositoryError, ChangesetError
34 from vcs.nodes import FileNode
34 from vcs.nodes import FileNode
35 from vcs.utils import diffs as differ
35 from vcs.utils import diffs as differ
36 import logging
36 import logging
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38 import tempfile
38 import tempfile
39
39
40 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
41
41
42 class FilesController(BaseController):
42 class FilesController(BaseController):
43
43
44 @LoginRequired()
44 @LoginRequired()
45 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
45 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
46 'repository.admin')
46 'repository.admin')
47 def __before__(self):
47 def __before__(self):
48 super(FilesController, self).__before__()
48 super(FilesController, self).__before__()
49 c.file_size_limit = 250 * 1024 #limit of file size to display
49 c.file_size_limit = 250 * 1024 #limit of file size to display
50
50
51 def index(self, repo_name, revision, f_path):
51 def index(self, repo_name, revision, f_path):
52 hg_model = HgModel()
52 hg_model = HgModel()
53 c.repo = repo = hg_model.get_repo(c.repo_name)
53 c.repo = repo = hg_model.get_repo(c.repo_name)
54 revision = request.POST.get('at_rev', None) or revision
54 revision = request.POST.get('at_rev', None) or revision
55
55
56 def get_next_rev(cur):
56 def get_next_rev(cur):
57 max_rev = len(c.repo.revisions) - 1
57 max_rev = len(c.repo.revisions) - 1
58 r = cur + 1
58 r = cur + 1
59 if r > max_rev:
59 if r > max_rev:
60 r = max_rev
60 r = max_rev
61 return r
61 return r
62
62
63 def get_prev_rev(cur):
63 def get_prev_rev(cur):
64 r = cur - 1
64 r = cur - 1
65 return r
65 return r
66
66
67 c.f_path = f_path
67 c.f_path = f_path
68
68
69
69
70 try:
70 try:
71 cur_rev = repo.get_changeset(revision).revision
71 c.changeset = repo.get_changeset(revision)
72 cur_rev = c.changeset.revision
72 prev_rev = repo.get_changeset(get_prev_rev(cur_rev)).raw_id
73 prev_rev = repo.get_changeset(get_prev_rev(cur_rev)).raw_id
73 next_rev = repo.get_changeset(get_next_rev(cur_rev)).raw_id
74 next_rev = repo.get_changeset(get_next_rev(cur_rev)).raw_id
74
75
75 c.url_prev = url('files_home', repo_name=c.repo_name,
76 c.url_prev = url('files_home', repo_name=c.repo_name,
76 revision=prev_rev, f_path=f_path)
77 revision=prev_rev, f_path=f_path)
77 c.url_next = url('files_home', repo_name=c.repo_name,
78 c.url_next = url('files_home', repo_name=c.repo_name,
78 revision=next_rev, f_path=f_path)
79 revision=next_rev, f_path=f_path)
79
80
80 c.changeset = repo.get_changeset(revision)
81 try:
82 c.files_list = c.changeset.get_node(f_path)
83 c.file_history = self._get_history(repo, c.files_list, f_path)
81
84
82 c.cur_rev = c.changeset.raw_id
85 except RepositoryError, e:
83 c.rev_nr = c.changeset.revision
86 h.flash(str(e), category='warning')
84 c.files_list = c.changeset.get_node(f_path)
87 redirect(h.url('files_home', repo_name=repo_name, revision=revision))
85 c.file_history = self._get_history(repo, c.files_list, f_path)
86
88
87 except (RepositoryError, ChangesetError):
89 except RepositoryError, e:
88 c.files_list = None
90 h.flash(str(e), category='warning')
91 redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
92
93
89
94
90 return render('files/files.html')
95 return render('files/files.html')
91
96
92 def rawfile(self, repo_name, revision, f_path):
97 def rawfile(self, repo_name, revision, f_path):
93 hg_model = HgModel()
98 hg_model = HgModel()
94 c.repo = hg_model.get_repo(c.repo_name)
99 c.repo = hg_model.get_repo(c.repo_name)
95 file_node = c.repo.get_changeset(revision).get_node(f_path)
100 file_node = c.repo.get_changeset(revision).get_node(f_path)
96 response.content_type = file_node.mimetype
101 response.content_type = file_node.mimetype
97 response.content_disposition = 'attachment; filename=%s' \
102 response.content_disposition = 'attachment; filename=%s' \
98 % f_path.split('/')[-1]
103 % f_path.split('/')[-1]
99 return file_node.content
104 return file_node.content
100
105
101 def raw(self, repo_name, revision, f_path):
106 def raw(self, repo_name, revision, f_path):
102 hg_model = HgModel()
107 hg_model = HgModel()
103 c.repo = hg_model.get_repo(c.repo_name)
108 c.repo = hg_model.get_repo(c.repo_name)
104 file_node = c.repo.get_changeset(revision).get_node(f_path)
109 file_node = c.repo.get_changeset(revision).get_node(f_path)
105 response.content_type = 'text/plain'
110 response.content_type = 'text/plain'
106
111
107 return file_node.content
112 return file_node.content
108
113
109 def annotate(self, repo_name, revision, f_path):
114 def annotate(self, repo_name, revision, f_path):
110 hg_model = HgModel()
115 hg_model = HgModel()
111 c.repo = hg_model.get_repo(c.repo_name)
116 c.repo = hg_model.get_repo(c.repo_name)
112 cs = c.repo.get_changeset(revision)
117 cs = c.repo.get_changeset(revision)
113 c.file = cs.get_node(f_path)
118 c.file = cs.get_node(f_path)
114 c.file_msg = cs.get_file_message(f_path)
119 c.file_msg = cs.get_file_message(f_path)
115 c.cur_rev = cs.raw_id
120 c.cur_rev = cs.raw_id
116 c.rev_nr = cs.revision
121 c.rev_nr = cs.revision
117 c.f_path = f_path
122 c.f_path = f_path
118
123
119 return render('files/files_annotate.html')
124 return render('files/files_annotate.html')
120
125
121 def archivefile(self, repo_name, revision, fileformat):
126 def archivefile(self, repo_name, revision, fileformat):
122 archive_specs = {
127 archive_specs = {
123 '.tar.bz2': ('application/x-tar', 'tbz2'),
128 '.tar.bz2': ('application/x-tar', 'tbz2'),
124 '.tar.gz': ('application/x-tar', 'tgz'),
129 '.tar.gz': ('application/x-tar', 'tgz'),
125 '.zip': ('application/zip', 'zip'),
130 '.zip': ('application/zip', 'zip'),
126 }
131 }
127 if not archive_specs.has_key(fileformat):
132 if not archive_specs.has_key(fileformat):
128 return 'Unknown archive type %s' % fileformat
133 return 'Unknown archive type %s' % fileformat
129
134
130 def read_in_chunks(file_object, chunk_size=1024 * 40):
135 def read_in_chunks(file_object, chunk_size=1024 * 40):
131 """Lazy function (generator) to read a file piece by piece.
136 """Lazy function (generator) to read a file piece by piece.
132 Default chunk size: 40k."""
137 Default chunk size: 40k."""
133 while True:
138 while True:
134 data = file_object.read(chunk_size)
139 data = file_object.read(chunk_size)
135 if not data:
140 if not data:
136 break
141 break
137 yield data
142 yield data
138
143
139 archive = tempfile.TemporaryFile()
144 archive = tempfile.TemporaryFile()
140 repo = HgModel().get_repo(repo_name).repo
145 repo = HgModel().get_repo(repo_name).repo
141 fname = '%s-%s%s' % (repo_name, revision, fileformat)
146 fname = '%s-%s%s' % (repo_name, revision, fileformat)
142 archival.archive(repo, archive, revision, archive_specs[fileformat][1],
147 archival.archive(repo, archive, revision, archive_specs[fileformat][1],
143 prefix='%s-%s' % (repo_name, revision))
148 prefix='%s-%s' % (repo_name, revision))
144 response.content_type = archive_specs[fileformat][0]
149 response.content_type = archive_specs[fileformat][0]
145 response.content_disposition = 'attachment; filename=%s' % fname
150 response.content_disposition = 'attachment; filename=%s' % fname
146 archive.seek(0)
151 archive.seek(0)
147 return read_in_chunks(archive)
152 return read_in_chunks(archive)
148
153
149 def diff(self, repo_name, f_path):
154 def diff(self, repo_name, f_path):
150 hg_model = HgModel()
155 hg_model = HgModel()
151 diff1 = request.GET.get('diff1')
156 diff1 = request.GET.get('diff1')
152 diff2 = request.GET.get('diff2')
157 diff2 = request.GET.get('diff2')
153 c.action = request.GET.get('diff')
158 c.action = request.GET.get('diff')
154 c.no_changes = diff1 == diff2
159 c.no_changes = diff1 == diff2
155 c.f_path = f_path
160 c.f_path = f_path
156 c.repo = hg_model.get_repo(c.repo_name)
161 c.repo = hg_model.get_repo(c.repo_name)
157
162
158 try:
163 try:
159 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
164 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
160 c.changeset_1 = c.repo.get_changeset(diff1)
165 c.changeset_1 = c.repo.get_changeset(diff1)
161 node1 = c.changeset_1.get_node(f_path)
166 node1 = c.changeset_1.get_node(f_path)
162 else:
167 else:
163 c.changeset_1 = EmptyChangeset()
168 c.changeset_1 = EmptyChangeset()
164 node1 = FileNode('.', '', changeset=c.changeset_1)
169 node1 = FileNode('.', '', changeset=c.changeset_1)
165
170
166 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
171 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
167 c.changeset_2 = c.repo.get_changeset(diff2)
172 c.changeset_2 = c.repo.get_changeset(diff2)
168 node2 = c.changeset_2.get_node(f_path)
173 node2 = c.changeset_2.get_node(f_path)
169 else:
174 else:
170 c.changeset_2 = EmptyChangeset()
175 c.changeset_2 = EmptyChangeset()
171 node2 = FileNode('.', '', changeset=c.changeset_2)
176 node2 = FileNode('.', '', changeset=c.changeset_2)
172 except RepositoryError:
177 except RepositoryError:
173 return redirect(url('files_home',
178 return redirect(url('files_home',
174 repo_name=c.repo_name, f_path=f_path))
179 repo_name=c.repo_name, f_path=f_path))
175
180
176 f_udiff = differ.get_udiff(node1, node2)
181 f_udiff = differ.get_udiff(node1, node2)
177 diff = differ.DiffProcessor(f_udiff)
182 diff = differ.DiffProcessor(f_udiff)
178
183
179 if c.action == 'download':
184 if c.action == 'download':
180 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
185 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
181 response.content_type = 'text/plain'
186 response.content_type = 'text/plain'
182 response.content_disposition = 'attachment; filename=%s' \
187 response.content_disposition = 'attachment; filename=%s' \
183 % diff_name
188 % diff_name
184 return diff.raw_diff()
189 return diff.raw_diff()
185
190
186 elif c.action == 'raw':
191 elif c.action == 'raw':
187 c.cur_diff = '<pre class="raw">%s</pre>' % h.escape(diff.raw_diff())
192 c.cur_diff = '<pre class="raw">%s</pre>' % h.escape(diff.raw_diff())
188 elif c.action == 'diff':
193 elif c.action == 'diff':
189 if node1.size > c.file_size_limit or node2.size > c.file_size_limit:
194 if node1.size > c.file_size_limit or node2.size > c.file_size_limit:
190 c.cur_diff = _('Diff is to big to display')
195 c.cur_diff = _('Diff is to big to display')
191 else:
196 else:
192 c.cur_diff = diff.as_html()
197 c.cur_diff = diff.as_html()
193 else:
198 else:
194 #default option
199 #default option
195 if node1.size > c.file_size_limit or node2.size > c.file_size_limit:
200 if node1.size > c.file_size_limit or node2.size > c.file_size_limit:
196 c.cur_diff = _('Diff is to big to display')
201 c.cur_diff = _('Diff is to big to display')
197 else:
202 else:
198 c.cur_diff = diff.as_html()
203 c.cur_diff = diff.as_html()
199
204
200 if not c.cur_diff: c.no_changes = True
205 if not c.cur_diff: c.no_changes = True
201 return render('files/file_diff.html')
206 return render('files/file_diff.html')
202
207
203 def _get_history(self, repo, node, f_path):
208 def _get_history(self, repo, node, f_path):
204 from vcs.nodes import NodeKind
209 from vcs.nodes import NodeKind
205 if not node.kind is NodeKind.FILE:
210 if not node.kind is NodeKind.FILE:
206 return []
211 return []
207 changesets = node.history
212 changesets = node.history
208 hist_l = []
213 hist_l = []
209 for chs in changesets:
214 for chs in changesets:
210 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
215 n_desc = 'r%s:%s' % (chs.revision, chs.short_id)
211 hist_l.append((chs.raw_id, n_desc,))
216 hist_l.append((chs.raw_id, n_desc,))
212 return hist_l
217 return hist_l
@@ -1,48 +1,55 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} ${_('Files')} - ${c.rhodecode_name}
4 ${c.repo_name} ${_('Files')} - ${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('files_home',repo_name=c.repo_name))}
10 ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))}
11 &raquo;
11 &raquo;
12 ${_('files')}
12 ${_('files')}
13 %if c.files_list:
13 %if c.files_list:
14 @ R${c.rev_nr}:${h.short_id(c.cur_rev)}
14 @ r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)}
15 %endif
15 %endif
16 </%def>
16 </%def>
17
17
18 <%def name="page_nav()">
18 <%def name="page_nav()">
19 ${self.menu('files')}
19 ${self.menu('files')}
20 </%def>
20 </%def>
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box">
23 <div class="box">
24 <!-- box / title -->
24 <!-- box / title -->
25 <div class="title">
25 <div class="title">
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 <ul class="links">
28 <li>
29 <span style="text-transform: uppercase;"><a href="#">${_('branch')}: ${c.changeset.branch}</a></span>
30 </li>
31 </ul>
27 </div>
32 </div>
28 <div class="table">
33 <div class="table">
29 <div id="files_data">
34 <div id="files_data">
30 %if c.files_list:
35 %if c.files_list:
31 <h3 class="files_location">${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.files_list.path)}</h3>
36 <h3 class="files_location">
37 ${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.changeset.raw_id,c.files_list.path)}
38 </h3>
32 %if c.files_list.is_dir():
39 %if c.files_list.is_dir():
33 <%include file='files_browser.html'/>
40 <%include file='files_browser.html'/>
34 %else:
41 %else:
35 <%include file='files_source.html'/>
42 <%include file='files_source.html'/>
36 %endif
43 %endif
37 %else:
44 %else:
38 <h2>
45 <h2>
39 <a href="#" onClick="javascript:parent.history.back();" target="main">${_('Go back')}</a>
46 <a href="#" onClick="javascript:parent.history.back();" target="main">${_('Go back')}</a>
40 ${_('No files at given path')}: "${c.f_path or "/"}"
47 ${_('No files at given path')}: "${c.f_path or "/"}"
41 </h2>
48 </h2>
42 %endif
49 %endif
43
50
44 </div>
51 </div>
45 </div>
52 </div>
46 </div>
53 </div>
47
54
48 </%def> No newline at end of file
55 </%def>
@@ -1,80 +1,80 b''
1 <%def name="file_class(node)">
1 <%def name="file_class(node)">
2 %if node.is_file():
2 %if node.is_file():
3 <%return "browser-file" %>
3 <%return "browser-file" %>
4 %else:
4 %else:
5 <%return "browser-dir"%>
5 <%return "browser-dir"%>
6 %endif
6 %endif
7 </%def>
7 </%def>
8 <div id="body" class="browserblock">
8 <div id="body" class="browserblock">
9 <div class="browser-header">
9 <div class="browser-header">
10 ${h.form(h.url.current())}
10 ${h.form(h.url.current())}
11 <div class="info_box">
11 <div class="info_box">
12 <span >${_('view')}@rev</span>
12 <span >${_('view')}@rev</span>
13 <a href="${c.url_prev}">&laquo;</a>
13 <a href="${c.url_prev}" title="${_('previous revision')}">&laquo;</a>
14 ${h.text('at_rev',value=c.rev_nr,size=3)}
14 ${h.text('at_rev',value=c.changeset.revision,size=3)}
15 <a href="${c.url_next}">&raquo;</a>
15 <a href="${c.url_next}" title="${_('next revision')}">&raquo;</a>
16 ${h.submit('view','view')}
16 ${h.submit('view','view')}
17 </div>
17 </div>
18 ${h.end_form()}
18 ${h.end_form()}
19 </div>
19 </div>
20 <div class="browser-body">
20 <div class="browser-body">
21 <table class="code-browser">
21 <table class="code-browser">
22 <thead>
22 <thead>
23 <tr>
23 <tr>
24 <th>${_('Name')}</th>
24 <th>${_('Name')}</th>
25 <th>${_('Size')}</th>
25 <th>${_('Size')}</th>
26 <th>${_('Mimetype')}</th>
26 <th>${_('Mimetype')}</th>
27 <th>${_('Revision')}</th>
27 <th>${_('Revision')}</th>
28 <th>${_('Last modified')}</th>
28 <th>${_('Last modified')}</th>
29 <th>${_('Last commiter')}</th>
29 <th>${_('Last commiter')}</th>
30 </tr>
30 </tr>
31 </thead>
31 </thead>
32
32
33 %if c.files_list.parent:
33 %if c.files_list.parent:
34 <tr class="parity0">
34 <tr class="parity0">
35 <td>
35 <td>
36 ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.files_list.parent.path),class_="browser-dir")}
36 ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.files_list.parent.path),class_="browser-dir")}
37 </td>
37 </td>
38 <td></td>
38 <td></td>
39 <td></td>
39 <td></td>
40 <td></td>
40 <td></td>
41 <td></td>
41 <td></td>
42 <td></td>
42 <td></td>
43 </tr>
43 </tr>
44 %endif
44 %endif
45
45
46 %for cnt,node in enumerate(c.files_list,1):
46 %for cnt,node in enumerate(c.files_list,1):
47 <tr class="parity${cnt%2}">
47 <tr class="parity${cnt%2}">
48 <td>
48 <td>
49 ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=node.path),class_=file_class(node))}
49 ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=node.path),class_=file_class(node))}
50 </td>
50 </td>
51 <td>
51 <td>
52 %if node.is_file():
52 %if node.is_file():
53 ${h.format_byte_size(node.size,binary=True)}
53 ${h.format_byte_size(node.size,binary=True)}
54 %endif
54 %endif
55 </td>
55 </td>
56 <td>
56 <td>
57 %if node.is_file():
57 %if node.is_file():
58 ${node.mimetype}
58 ${node.mimetype}
59 %endif
59 %endif
60 </td>
60 </td>
61 <td>
61 <td>
62 %if node.is_file():
62 %if node.is_file():
63 ${node.last_changeset.revision}
63 <span class="tooltip" tooltip_title="${node.last_changeset.raw_id}">${node.last_changeset.revision}</span>
64 %endif
64 %endif
65 </td>
65 </td>
66 <td>
66 <td>
67 %if node.is_file():
67 %if node.is_file():
68 ${h.age(node.last_changeset.date)} - ${node.last_changeset.date}
68 ${node.last_changeset.date} - ${h.age(node.last_changeset.date)} ${_('ago')}
69 %endif
69 %endif
70 </td>
70 </td>
71 <td>
71 <td>
72 %if node.is_file():
72 %if node.is_file():
73 ${node.last_changeset.author}
73 ${node.last_changeset.author}
74 %endif
74 %endif
75 </td>
75 </td>
76 </tr>
76 </tr>
77 %endfor
77 %endfor
78 </table>
78 </table>
79 </div>
79 </div>
80 </div> No newline at end of file
80 </div>
@@ -1,57 +1,57 b''
1 <dl>
1 <dl>
2 <dt>${_('Last revision')}</dt>
2 <dt>${_('Last 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('files_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id,f_path=c.f_path))}
5 h.url('files_home',repo_name=c.repo_name,revision=c.files_list.last_changeset.raw_id,f_path=c.f_path))}
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.cur_rev,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.cur_rev,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.cur_rev,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 ui-widget ui-state-default ui-corner-all")}
25 ${h.submit('diff','diff to revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
26 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
26 ${h.submit('show_rev','show at revision',class_="ui-button ui-widget ui-state-default ui-corner-all")}
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.size < c.file_size_limit:
39 % if c.files_list.size < c.file_size_limit:
40 ${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
40 ${h.pygmentize(c.files_list,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
41 %else:
41 %else:
42 ${_('File is to big to display')} ${h.link_to(_('show as raw'),
42 ${_('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.cur_rev,f_path=c.f_path))}
43 h.url('files_raw_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=c.f_path))}
44 %endif
44 %endif
45 </div>
45 </div>
46 </div>
46 </div>
47
47
48 <script type="text/javascript">
48 <script type="text/javascript">
49 YAHOO.util.Event.onDOMReady(function(){
49 YAHOO.util.Event.onDOMReady(function(){
50 YAHOO.util.Event.addListener('show_rev','click',function(e){
50 YAHOO.util.Event.addListener('show_rev','click',function(e){
51 YAHOO.util.Event.preventDefault(e);
51 YAHOO.util.Event.preventDefault(e);
52 var cs = YAHOO.util.Dom.get('diff1').value;
52 var cs = YAHOO.util.Dom.get('diff1').value;
53 var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
53 var url = "${h.url('files_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
54 window.location = url;
54 window.location = url;
55 });
55 });
56 });
56 });
57 </script> No newline at end of file
57 </script>
General Comments 0
You need to be logged in to leave comments. Login now