##// END OF EJS Templates
sorted tags by date in tag view
marcink -
r1126:e6548981 beta
parent child Browse files
Show More
@@ -1,213 +1,213
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.changeset
3 rhodecode.controllers.changeset
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 changeset controller for pylons showoing changes beetween
6 changeset controller for pylons showoing changes beetween
7 revisions
7 revisions
8
8
9 :created_on: Apr 25, 2010
9 :created_on: Apr 25, 2010
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software; you can redistribute it and/or
14 # This program is free software; you can redistribute it and/or
15 # modify it under the terms of the GNU General Public License
15 # modify it under the terms of the GNU General Public License
16 # as published by the Free Software Foundation; version 2
16 # as published by the Free Software Foundation; version 2
17 # of the License or (at your opinion) any later version of the license.
17 # of the License or (at your opinion) any later version of the license.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27 # MA 02110-1301, USA.
27 # MA 02110-1301, USA.
28 import logging
28 import logging
29 import traceback
29 import traceback
30
30
31 from pylons import tmpl_context as c, url, request, response
31 from pylons import tmpl_context as c, url, request, response
32 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
33 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
34
34
35 import rhodecode.lib.helpers as h
35 import rhodecode.lib.helpers as h
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
37 from rhodecode.lib.base import BaseRepoController, render
37 from rhodecode.lib.base import BaseRepoController, render
38 from rhodecode.lib.utils import EmptyChangeset
38 from rhodecode.lib.utils import EmptyChangeset
39
39
40 from vcs.exceptions import RepositoryError, ChangesetError, \
40 from vcs.exceptions import RepositoryError, ChangesetError, \
41 ChangesetDoesNotExistError
41 ChangesetDoesNotExistError
42 from vcs.nodes import FileNode
42 from vcs.nodes import FileNode
43 from vcs.utils import diffs as differ
43 from vcs.utils import diffs as differ
44 from vcs.utils.ordered_dict import OrderedDict
44 from vcs.utils.ordered_dict import OrderedDict
45
45
46 log = logging.getLogger(__name__)
46 log = logging.getLogger(__name__)
47
47
48 class ChangesetController(BaseRepoController):
48 class ChangesetController(BaseRepoController):
49
49
50 @LoginRequired()
50 @LoginRequired()
51 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
51 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
52 'repository.admin')
52 'repository.admin')
53 def __before__(self):
53 def __before__(self):
54 super(ChangesetController, self).__before__()
54 super(ChangesetController, self).__before__()
55
55
56 def index(self, revision):
56 def index(self, revision):
57
57
58 def wrap_to_table(str):
58 def wrap_to_table(str):
59
59
60 return '''<table class="code-difftable">
60 return '''<table class="code-difftable">
61 <tr class="line">
61 <tr class="line">
62 <td class="lineno new"></td>
62 <td class="lineno new"></td>
63 <td class="code"><pre>%s</pre></td>
63 <td class="code"><pre>%s</pre></td>
64 </tr>
64 </tr>
65 </table>''' % str
65 </table>''' % str
66
66
67 #get ranges of revisions if preset
67 #get ranges of revisions if preset
68 rev_range = revision.split('...')[:2]
68 rev_range = revision.split('...')[:2]
69 range_limit = 50
69
70 try:
70 try:
71 if len(rev_range) == 2:
71 if len(rev_range) == 2:
72 rev_start = rev_range[0]
72 rev_start = rev_range[0]
73 rev_end = rev_range[1]
73 rev_end = rev_range[1]
74 rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
74 rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
75 end=rev_end)
75 end=rev_end)
76 else:
76 else:
77 rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
77 rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
78
78
79 c.cs_ranges = list(rev_ranges)
79 c.cs_ranges = list(rev_ranges)
80
80
81 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
81 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
82 log.error(traceback.format_exc())
82 log.error(traceback.format_exc())
83 h.flash(str(e), category='warning')
83 h.flash(str(e), category='warning')
84 return redirect(url('home'))
84 return redirect(url('home'))
85
85
86 c.changes = OrderedDict()
86 c.changes = OrderedDict()
87 c.sum_added = 0
87 c.sum_added = 0
88 c.sum_removed = 0
88 c.sum_removed = 0
89
89
90
90
91 for changeset in c.cs_ranges:
91 for changeset in c.cs_ranges:
92 c.changes[changeset.raw_id] = []
92 c.changes[changeset.raw_id] = []
93 try:
93 try:
94 changeset_parent = changeset.parents[0]
94 changeset_parent = changeset.parents[0]
95 except IndexError:
95 except IndexError:
96 changeset_parent = None
96 changeset_parent = None
97
97
98
98
99 #==================================================================
99 #==================================================================
100 # ADDED FILES
100 # ADDED FILES
101 #==================================================================
101 #==================================================================
102 for node in changeset.added:
102 for node in changeset.added:
103 filenode_old = FileNode(node.path, '', EmptyChangeset())
103 filenode_old = FileNode(node.path, '', EmptyChangeset())
104 if filenode_old.is_binary or node.is_binary:
104 if filenode_old.is_binary or node.is_binary:
105 diff = wrap_to_table(_('binary file'))
105 diff = wrap_to_table(_('binary file'))
106 else:
106 else:
107 c.sum_added += node.size
107 c.sum_added += node.size
108 if c.sum_added < self.cut_off_limit:
108 if c.sum_added < self.cut_off_limit:
109 f_gitdiff = differ.get_gitdiff(filenode_old, node)
109 f_gitdiff = differ.get_gitdiff(filenode_old, node)
110 diff = differ.DiffProcessor(f_gitdiff, format='gitdiff').as_html()
110 diff = differ.DiffProcessor(f_gitdiff, format='gitdiff').as_html()
111
111
112 else:
112 else:
113 diff = wrap_to_table(_('Changeset is to big and was cut'
113 diff = wrap_to_table(_('Changeset is to big and was cut'
114 ' off, see raw changeset instead'))
114 ' off, see raw changeset instead'))
115
115
116 cs1 = None
116 cs1 = None
117 cs2 = node.last_changeset.raw_id
117 cs2 = node.last_changeset.raw_id
118 c.changes[changeset.raw_id].append(('added', node, diff, cs1, cs2))
118 c.changes[changeset.raw_id].append(('added', node, diff, cs1, cs2))
119
119
120 #==================================================================
120 #==================================================================
121 # CHANGED FILES
121 # CHANGED FILES
122 #==================================================================
122 #==================================================================
123 for node in changeset.changed:
123 for node in changeset.changed:
124 try:
124 try:
125 filenode_old = changeset_parent.get_node(node.path)
125 filenode_old = changeset_parent.get_node(node.path)
126 except ChangesetError:
126 except ChangesetError:
127 filenode_old = FileNode(node.path, '', EmptyChangeset())
127 filenode_old = FileNode(node.path, '', EmptyChangeset())
128
128
129 if filenode_old.is_binary or node.is_binary:
129 if filenode_old.is_binary or node.is_binary:
130 diff = wrap_to_table(_('binary file'))
130 diff = wrap_to_table(_('binary file'))
131 else:
131 else:
132
132
133 if c.sum_removed < self.cut_off_limit:
133 if c.sum_removed < self.cut_off_limit:
134 f_gitdiff = differ.get_gitdiff(filenode_old, node)
134 f_gitdiff = differ.get_gitdiff(filenode_old, node)
135 diff = differ.DiffProcessor(f_gitdiff, format='gitdiff').as_html()
135 diff = differ.DiffProcessor(f_gitdiff, format='gitdiff').as_html()
136 if diff:
136 if diff:
137 c.sum_removed += len(diff)
137 c.sum_removed += len(diff)
138 else:
138 else:
139 diff = wrap_to_table(_('Changeset is to big and was cut'
139 diff = wrap_to_table(_('Changeset is to big and was cut'
140 ' off, see raw changeset instead'))
140 ' off, see raw changeset instead'))
141
141
142
142
143 cs1 = filenode_old.last_changeset.raw_id
143 cs1 = filenode_old.last_changeset.raw_id
144 cs2 = node.last_changeset.raw_id
144 cs2 = node.last_changeset.raw_id
145 c.changes[changeset.raw_id].append(('changed', node, diff, cs1, cs2))
145 c.changes[changeset.raw_id].append(('changed', node, diff, cs1, cs2))
146
146
147 #==================================================================
147 #==================================================================
148 # REMOVED FILES
148 # REMOVED FILES
149 #==================================================================
149 #==================================================================
150 for node in changeset.removed:
150 for node in changeset.removed:
151 c.changes[changeset.raw_id].append(('removed', node, None, None, None))
151 c.changes[changeset.raw_id].append(('removed', node, None, None, None))
152
152
153 if len(c.cs_ranges) == 1:
153 if len(c.cs_ranges) == 1:
154 c.changeset = c.cs_ranges[0]
154 c.changeset = c.cs_ranges[0]
155 c.changes = c.changes[c.changeset.raw_id]
155 c.changes = c.changes[c.changeset.raw_id]
156
156
157 return render('changeset/changeset.html')
157 return render('changeset/changeset.html')
158 else:
158 else:
159 return render('changeset/changeset_range.html')
159 return render('changeset/changeset_range.html')
160
160
161 def raw_changeset(self, revision):
161 def raw_changeset(self, revision):
162
162
163 method = request.GET.get('diff', 'show')
163 method = request.GET.get('diff', 'show')
164 try:
164 try:
165 c.scm_type = c.rhodecode_repo.alias
165 c.scm_type = c.rhodecode_repo.alias
166 c.changeset = c.rhodecode_repo.get_changeset(revision)
166 c.changeset = c.rhodecode_repo.get_changeset(revision)
167 except RepositoryError:
167 except RepositoryError:
168 log.error(traceback.format_exc())
168 log.error(traceback.format_exc())
169 return redirect(url('home'))
169 return redirect(url('home'))
170 else:
170 else:
171 try:
171 try:
172 c.changeset_parent = c.changeset.parents[0]
172 c.changeset_parent = c.changeset.parents[0]
173 except IndexError:
173 except IndexError:
174 c.changeset_parent = None
174 c.changeset_parent = None
175 c.changes = []
175 c.changes = []
176
176
177 for node in c.changeset.added:
177 for node in c.changeset.added:
178 filenode_old = FileNode(node.path, '')
178 filenode_old = FileNode(node.path, '')
179 if filenode_old.is_binary or node.is_binary:
179 if filenode_old.is_binary or node.is_binary:
180 diff = _('binary file') + '\n'
180 diff = _('binary file') + '\n'
181 else:
181 else:
182 f_gitdiff = differ.get_gitdiff(filenode_old, node)
182 f_gitdiff = differ.get_gitdiff(filenode_old, node)
183 diff = differ.DiffProcessor(f_gitdiff).raw_diff()
183 diff = differ.DiffProcessor(f_gitdiff).raw_diff()
184
184
185 cs1 = None
185 cs1 = None
186 cs2 = node.last_changeset.raw_id
186 cs2 = node.last_changeset.raw_id
187 c.changes.append(('added', node, diff, cs1, cs2))
187 c.changes.append(('added', node, diff, cs1, cs2))
188
188
189 for node in c.changeset.changed:
189 for node in c.changeset.changed:
190 filenode_old = c.changeset_parent.get_node(node.path)
190 filenode_old = c.changeset_parent.get_node(node.path)
191 if filenode_old.is_binary or node.is_binary:
191 if filenode_old.is_binary or node.is_binary:
192 diff = _('binary file')
192 diff = _('binary file')
193 else:
193 else:
194 f_gitdiff = differ.get_gitdiff(filenode_old, node)
194 f_gitdiff = differ.get_gitdiff(filenode_old, node)
195 diff = differ.DiffProcessor(f_gitdiff).raw_diff()
195 diff = differ.DiffProcessor(f_gitdiff).raw_diff()
196
196
197 cs1 = filenode_old.last_changeset.raw_id
197 cs1 = filenode_old.last_changeset.raw_id
198 cs2 = node.last_changeset.raw_id
198 cs2 = node.last_changeset.raw_id
199 c.changes.append(('changed', node, diff, cs1, cs2))
199 c.changes.append(('changed', node, diff, cs1, cs2))
200
200
201 response.content_type = 'text/plain'
201 response.content_type = 'text/plain'
202
202
203 if method == 'download':
203 if method == 'download':
204 response.content_disposition = 'attachment; filename=%s.patch' % revision
204 response.content_disposition = 'attachment; filename=%s.patch' % revision
205
205
206 parent = True if len(c.changeset.parents) > 0 else False
206 parent = True if len(c.changeset.parents) > 0 else False
207 c.parent_tmpl = 'Parent %s' % c.changeset.parents[0].raw_id if parent else ''
207 c.parent_tmpl = 'Parent %s' % c.changeset.parents[0].raw_id if parent else ''
208
208
209 c.diffs = ''
209 c.diffs = ''
210 for x in c.changes:
210 for x in c.changes:
211 c.diffs += x[2]
211 c.diffs += x[2]
212
212
213 return render('changeset/raw_changeset.html')
213 return render('changeset/raw_changeset.html')
@@ -1,50 +1,54
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.tags
3 rhodecode.controllers.tags
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Tags controller for rhodecode
6 Tags 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 logging
27 import logging
28
28
29 from pylons import tmpl_context as c
29 from pylons import tmpl_context as c
30
30
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
32 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.lib.base import BaseRepoController, render
33 from rhodecode.lib.utils import OrderedDict
33 from rhodecode.lib.utils import OrderedDict
34
34
35 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
36
36
37 class TagsController(BaseRepoController):
37 class TagsController(BaseRepoController):
38
38
39 @LoginRequired()
39 @LoginRequired()
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
41 'repository.admin')
41 'repository.admin')
42 def __before__(self):
42 def __before__(self):
43 super(TagsController, self).__before__()
43 super(TagsController, self).__before__()
44
44
45 def index(self):
45 def index(self):
46 c.repo_tags = OrderedDict()
46 c.repo_tags = OrderedDict()
47 for name, hash_ in c.rhodecode_repo.tags.items():
47
48 c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash_)
48 tags = [(name, c.rhodecode_repo.get_changeset(hash_)) for \
49 name, hash_ in c.rhodecode_repo.tags.items()]
50 ordered_tags = sorted(tags, key=lambda x:x[1].date, reverse=True)
51 for name, cs_tag in ordered_tags:
52 c.repo_tags[name] = cs_tag
49
53
50 return render('tags/tags.html')
54 return render('tags/tags.html')
General Comments 0
You need to be logged in to leave comments. Login now