##// END OF EJS Templates
pep8ify + small fixes for followers page + added tooltips for followers
marcink -
r1280:215a4801 beta
parent child Browse files
Show More
@@ -1,254 +1,253
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.changeset
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 changeset controller for pylons showoing changes beetween
7 7 revisions
8 8
9 9 :created_on: Apr 25, 2010
10 10 :author: marcink
11 11 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
12 12 :license: GPLv3, see COPYING for more details.
13 13 """
14 14 # This program is free software: you can redistribute it and/or modify
15 15 # it under the terms of the GNU General Public License as published by
16 16 # the Free Software Foundation, either version 3 of the License, or
17 17 # (at your option) any later version.
18 18 #
19 19 # This program is distributed in the hope that it will be useful,
20 20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 22 # GNU General Public License for more details.
23 23 #
24 24 # You should have received a copy of the GNU General Public License
25 25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 26 import logging
27 27 import traceback
28 28
29 29 from pylons import tmpl_context as c, url, request, response
30 30 from pylons.i18n.translation import _
31 31 from pylons.controllers.util import redirect
32 32
33 33 import rhodecode.lib.helpers as h
34 34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 35 from rhodecode.lib.base import BaseRepoController, render
36 36 from rhodecode.lib.utils import EmptyChangeset
37 37
38 38 from vcs.exceptions import RepositoryError, ChangesetError, \
39 39 ChangesetDoesNotExistError
40 40 from vcs.nodes import FileNode
41 41 from vcs.utils import diffs as differ
42 42 from vcs.utils.ordered_dict import OrderedDict
43 43
44 44 log = logging.getLogger(__name__)
45 45
46 46
47 47 class ChangesetController(BaseRepoController):
48 48
49 49 @LoginRequired()
50 50 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
51 51 'repository.admin')
52 52 def __before__(self):
53 53 super(ChangesetController, self).__before__()
54 54 c.affected_files_cut_off = 60
55 55
56 56 def index(self, revision):
57 57
58 58 def wrap_to_table(str):
59 59
60 60 return '''<table class="code-difftable">
61 61 <tr class="line">
62 62 <td class="lineno new"></td>
63 63 <td class="code"><pre>%s</pre></td>
64 64 </tr>
65 65 </table>''' % str
66 66
67 67 #get ranges of revisions if preset
68 68 rev_range = revision.split('...')[:2]
69 69
70 70 try:
71 71 if len(rev_range) == 2:
72 72 rev_start = rev_range[0]
73 73 rev_end = rev_range[1]
74 74 rev_ranges = c.rhodecode_repo.get_changesets(start=rev_start,
75 75 end=rev_end)
76 76 else:
77 77 rev_ranges = [c.rhodecode_repo.get_changeset(revision)]
78 78
79 79 c.cs_ranges = list(rev_ranges)
80 80
81 81 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
82 82 log.error(traceback.format_exc())
83 83 h.flash(str(e), category='warning')
84 84 return redirect(url('home'))
85 85
86 86 c.changes = OrderedDict()
87 87 c.sum_added = 0
88 88 c.sum_removed = 0
89 89 c.lines_added = 0
90 90 c.lines_deleted = 0
91 c.cut_off = False # defines if cut off limit is reached
91 c.cut_off = False # defines if cut off limit is reached
92 92
93 93 # Iterate over ranges (default changeset view is always one changeset)
94 94 for changeset in c.cs_ranges:
95 95 c.changes[changeset.raw_id] = []
96 96 try:
97 97 changeset_parent = changeset.parents[0]
98 98 except IndexError:
99 99 changeset_parent = None
100 100
101 101 #==================================================================
102 102 # ADDED FILES
103 103 #==================================================================
104 104 for node in changeset.added:
105 105
106 106 filenode_old = FileNode(node.path, '', EmptyChangeset())
107 107 if filenode_old.is_binary or node.is_binary:
108 108 diff = wrap_to_table(_('binary file'))
109 109 st = (0, 0)
110 110 else:
111 111 # in this case node.size is good parameter since those are
112 112 # added nodes and their size defines how many changes were
113 113 # made
114 114 c.sum_added += node.size
115 115 if c.sum_added < self.cut_off_limit:
116 116 f_gitdiff = differ.get_gitdiff(filenode_old, node)
117 117 d = differ.DiffProcessor(f_gitdiff, format='gitdiff')
118 118
119 119 st = d.stat()
120 120 diff = d.as_html()
121 121
122 122 else:
123 123 diff = wrap_to_table(_('Changeset is to big and '
124 124 'was cut off, see raw '
125 125 'changeset instead'))
126 126 c.cut_off = True
127 127 break
128 128
129 129 cs1 = None
130 130 cs2 = node.last_changeset.raw_id
131 131 c.lines_added += st[0]
132 132 c.lines_deleted += st[1]
133 133 c.changes[changeset.raw_id].append(('added', node, diff,
134 134 cs1, cs2, st))
135 135
136 136 #==================================================================
137 137 # CHANGED FILES
138 138 #==================================================================
139 139 if not c.cut_off:
140 140 for node in changeset.changed:
141 141 try:
142 142 filenode_old = changeset_parent.get_node(node.path)
143 143 except ChangesetError:
144 144 log.warning('Unable to fetch parent node for diff')
145 145 filenode_old = FileNode(node.path, '',
146 146 EmptyChangeset())
147 147
148 148 if filenode_old.is_binary or node.is_binary:
149 149 diff = wrap_to_table(_('binary file'))
150 150 st = (0, 0)
151 151 else:
152 152
153 153 if c.sum_removed < self.cut_off_limit:
154 154 f_gitdiff = differ.get_gitdiff(filenode_old, node)
155 155 d = differ.DiffProcessor(f_gitdiff,
156 156 format='gitdiff')
157 157 st = d.stat()
158 158 if (st[0] + st[1]) * 256 > self.cut_off_limit:
159 159 diff = wrap_to_table(_('Diff is to big '
160 160 'and was cut off, see '
161 161 'raw diff instead'))
162 162 else:
163 163 diff = d.as_html()
164 164
165
166 165 if diff:
167 166 c.sum_removed += len(diff)
168 167 else:
169 168 diff = wrap_to_table(_('Changeset is to big and '
170 169 'was cut off, see raw '
171 170 'changeset instead'))
172 171 c.cut_off = True
173 172 break
174 173
175 174 cs1 = filenode_old.last_changeset.raw_id
176 175 cs2 = node.last_changeset.raw_id
177 176 c.lines_added += st[0]
178 177 c.lines_deleted += st[1]
179 178 c.changes[changeset.raw_id].append(('changed', node, diff,
180 179 cs1, cs2, st))
181 180
182 181 #==================================================================
183 182 # REMOVED FILES
184 183 #==================================================================
185 184 if not c.cut_off:
186 185 for node in changeset.removed:
187 186 c.changes[changeset.raw_id].append(('removed', node, None,
188 187 None, None, (0, 0)))
189 188
190 189 if len(c.cs_ranges) == 1:
191 190 c.changeset = c.cs_ranges[0]
192 191 c.changes = c.changes[c.changeset.raw_id]
193 192
194 193 return render('changeset/changeset.html')
195 194 else:
196 195 return render('changeset/changeset_range.html')
197 196
198 197 def raw_changeset(self, revision):
199 198
200 199 method = request.GET.get('diff', 'show')
201 200 try:
202 201 c.scm_type = c.rhodecode_repo.alias
203 202 c.changeset = c.rhodecode_repo.get_changeset(revision)
204 203 except RepositoryError:
205 204 log.error(traceback.format_exc())
206 205 return redirect(url('home'))
207 206 else:
208 207 try:
209 208 c.changeset_parent = c.changeset.parents[0]
210 209 except IndexError:
211 210 c.changeset_parent = None
212 211 c.changes = []
213 212
214 213 for node in c.changeset.added:
215 214 filenode_old = FileNode(node.path, '')
216 215 if filenode_old.is_binary or node.is_binary:
217 216 diff = _('binary file') + '\n'
218 217 else:
219 218 f_gitdiff = differ.get_gitdiff(filenode_old, node)
220 219 diff = differ.DiffProcessor(f_gitdiff,
221 220 format='gitdiff').raw_diff()
222 221
223 222 cs1 = None
224 223 cs2 = node.last_changeset.raw_id
225 224 c.changes.append(('added', node, diff, cs1, cs2))
226 225
227 226 for node in c.changeset.changed:
228 227 filenode_old = c.changeset_parent.get_node(node.path)
229 228 if filenode_old.is_binary or node.is_binary:
230 229 diff = _('binary file')
231 230 else:
232 231 f_gitdiff = differ.get_gitdiff(filenode_old, node)
233 232 diff = differ.DiffProcessor(f_gitdiff,
234 233 format='gitdiff').raw_diff()
235 234
236 235 cs1 = filenode_old.last_changeset.raw_id
237 236 cs2 = node.last_changeset.raw_id
238 237 c.changes.append(('changed', node, diff, cs1, cs2))
239 238
240 239 response.content_type = 'text/plain'
241 240
242 241 if method == 'download':
243 242 response.content_disposition = 'attachment; filename=%s.patch' \
244 243 % revision
245 244
246 245 parent = True if len(c.changeset.parents) > 0 else False
247 246 c.parent_tmpl = 'Parent %s' \
248 247 % c.changeset.parents[0].raw_id if parent else ''
249 248
250 249 c.diffs = ''
251 250 for x in c.changes:
252 251 c.diffs += x[2]
253 252
254 253 return render('changeset/raw_changeset.html')
@@ -1,33 +1,32
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${c.repo_name} ${_('Followers')} - ${c.rhodecode_name}
6 6 </%def>
7 7
8
9 8 <%def name="breadcrumbs_links()">
10 9 ${h.link_to(u'Home',h.url('/'))}
11 10 &raquo;
12 11 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
13 12 &raquo;
14 13 ${_('followers')}
15 14 </%def>
16 15
17 16 <%def name="page_nav()">
18 17 ${self.menu('followers')}
19 18 </%def>
20 19 <%def name="main()">
21 20 <div class="box">
22 21 <!-- box / title -->
23 22 <div class="title">
24 23 ${self.breadcrumbs()}
25 24 </div>
26 25 <!-- end box / title -->
27 26 <div class="table">
28 27 <div id="followers">
29 28 ${c.followers_data}
30 29 </div>
31 30 </div>
32 31 </div>
33 32 </%def> No newline at end of file
@@ -1,37 +1,36
1 1 ## -*- coding: utf-8 -*-
2 2
3
4 3 % for f in c.followers_pager:
5 4 <div>
6 5 <div class="follower_user">
7 6 <div class="gravatar">
8 7 <img alt="gravatar" src="${h.gravatar_url(f.user.email,24)}"/>
9 8 </div>
10 9 <span style="font-size: 20px"> <b>${f.user.username}</b> (${f.user.name} ${f.user.lastname})</span>
11 10 </div>
12 11 <div style="clear:both;padding-top: 10px"></div>
13 <div class="follower_date">${_('Started following on')} - ${f.follows_from}</div>
12 <div class="follower_date">${_('Started following')} -
13 <span class="tooltip" title="${f.follows_from}"> ${h.age(f.follows_from)}</span></div>
14 14 <div style="border-bottom: 1px solid #DDD;margin:10px 0px 10px 0px"></div>
15 15 </div>
16 16 % endfor
17 17
18
19 18 <div class="pagination-wh pagination-left">
20 19 <script type="text/javascript">
21 20 var data_div = 'followers';
22 21 YAHOO.util.Event.onDOMReady(function(){
23 22 YAHOO.util.Event.addListener(
24 23 YUD.getElementsByClassName('pager_link'),"click",
25 24 function(){
26 25 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');
27 26 });
28 27 });
29 28 </script>
30 29
31 30 ${c.followers_pager.pager('$link_previous ~2~ $link_next',
32 31 onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
33 32 success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
34 33 YUE.on(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
35 34 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
36 35 YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
37 36 </div> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now