##// END OF EJS Templates
Fixed sumamry page description bug...
marcink -
r690:4685f3ea beta
parent child Browse files
Show More
@@ -1,168 +1,177 b''
1 1 #!/usr/bin/env python
2 2 # encoding: utf-8
3 3 # Model for RhodeCode
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
9 9 # of the License or (at your opinion) any later version of the license.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20 20 """
21 21 Created on April 9, 2010
22 22 Model for RhodeCode
23 23 @author: marcink
24 24 """
25 25 from beaker.cache import cache_region, region_invalidate
26 26 from mercurial import ui
27 27 from rhodecode.lib import helpers as h
28 28 from rhodecode.lib.auth import HasRepoPermissionAny
29 29 from rhodecode.lib.utils import get_repos
30 30 from rhodecode.model import meta
31 from rhodecode.model.caching_query import FromCache
32 31 from rhodecode.model.db import Repository, User, RhodeCodeUi
33 32 from sqlalchemy.orm import joinedload
34 from vcs import get_repo as vcs_get_repo, get_backend
35 from vcs.backends.hg import MercurialRepository
33 from vcs import get_backend
34 from vcs.utils.helpers import get_scm
36 35 from vcs.exceptions import RepositoryError, VCSError
37 36 from vcs.utils.lazy import LazyProperty
38 37 import logging
39 38 import os
40 39 import time
41 40
42 41 log = logging.getLogger(__name__)
43 42
44 43 class HgModel(object):
45 44 """
46 45 Mercurial Model
47 46 """
48 47
49 48 def __init__(self, sa=None):
50 49 if not sa:
51 50 self.sa = meta.Session()
52 51 else:
53 52 self.sa = sa
54 53
55 54
56 55 @LazyProperty
57 56 def repos_path(self):
58 57 """
59 58 Get's the repositories root path from database
60 59 """
61 60 q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
62 61
63 62 return q.ui_value
64 63
65 64 def repo_scan(self, repos_path, baseui, initial=False):
66 65 """
67 66 Listing of repositories in given path. This path should not be a
68 67 repository itself. Return a dictionary of repository objects
69 68
70 69 :param repos_path: path to directory containing repositories
71 70 :param baseui
72 71 :param initial: initial scan
73 72 """
74 73 log.info('scanning for repositories in %s', repos_path)
75 74
76 75 if not isinstance(baseui, ui.ui):
77 76 baseui = ui.ui()
78 77 repos_list = {}
78
79 79 for name, path in get_repos(repos_path):
80 80 try:
81 81 if repos_list.has_key(name):
82 82 raise RepositoryError('Duplicate repository name %s '
83 83 'found in %s' % (name, path))
84 84 else:
85 85
86 86 klass = get_backend(path[0])
87 87
88 88 if path[0] == 'hg':
89 89 repos_list[name] = klass(path[1], baseui=baseui)
90 90
91 91 if path[0] == 'git':
92 92 repos_list[name] = klass(path[1])
93 93 except OSError:
94 94 continue
95 95
96 96 return repos_list
97 97
98 98 def get_repos(self, all_repos=None):
99 99 """
100 Get all repos from db and for each such repo make backend and
101 fetch dependent data from db
100 Get all repos from db and for each repo create it's backend instance.
101 and fill that backed with information from database
102
103 :param all_repos: give specific repositories list, good for filtering
102 104 """
103 105 if not all_repos:
104 106 all_repos = self.sa.query(Repository).all()
105 107
106 108 for r in all_repos:
107 109
108 110 repo = self.get(r.repo_name)
109 111
110 112 if repo is not None:
111 113 last_change = repo.last_change
112 114 tip = h.get_changeset_safe(repo, 'tip')
113 115
114 116 tmp_d = {}
115 117 tmp_d['name'] = repo.name
116 118 tmp_d['name_sort'] = tmp_d['name'].lower()
117 119 tmp_d['description'] = repo.dbrepo.description
118 120 tmp_d['description_sort'] = tmp_d['description']
119 121 tmp_d['last_change'] = last_change
120 122 tmp_d['last_change_sort'] = time.mktime(last_change.timetuple())
121 123 tmp_d['tip'] = tip.raw_id
122 124 tmp_d['tip_sort'] = tip.revision
123 125 tmp_d['rev'] = tip.revision
124 126 tmp_d['contact'] = repo.dbrepo.user.full_contact
125 127 tmp_d['contact_sort'] = tmp_d['contact']
126 128 tmp_d['repo_archives'] = list(repo._get_archives())
127 129 tmp_d['last_msg'] = tip.message
128 130 tmp_d['repo'] = repo
129 131 yield tmp_d
130 132
131 133 def get_repo(self, repo_name):
132 134 return self.get(repo_name)
133 135
134 136 def get(self, repo_name):
135 137 """
136 138 Get's repository from given name, creates BackendInstance and
137 139 propagates it's data from database with all additional information
138 140 :param repo_name:
139 141 """
140 142 if not HasRepoPermissionAny('repository.read', 'repository.write',
141 143 'repository.admin')(repo_name, 'get repo check'):
142 144 return
143 145
144 146 @cache_region('long_term', 'get_repo_cached_%s' % repo_name)
145 147 def _get_repo(repo_name):
146 148
147 repo = vcs_get_repo(os.path.join(self.repos_path, repo_name),
148 alias=None, create=False)
149 repo_path = os.path.join(self.repos_path, repo_name)
150 alias = get_scm(repo_path)[0]
151
152 log.debug('Creating instance of %s repository', alias)
153 backend = get_backend(alias)
149 154
150 #skip hidden web repository
151 if isinstance(repo, MercurialRepository) and repo._get_hidden():
152 return
155 if alias == 'hg':
156 repo = backend(repo_path, create=False, baseui=None)
157 #skip hidden web repository
158 if repo._get_hidden():
159 return
160 else:
161 repo = backend(repo_path, create=False)
153 162
154 163 dbrepo = self.sa.query(Repository)\
155 164 .options(joinedload(Repository.fork))\
156 165 .options(joinedload(Repository.user))\
157 166 .filter(Repository.repo_name == repo_name)\
158 167 .scalar()
159 168 repo.dbrepo = dbrepo
160 169 return repo
161 170
162 171 invalidate = False
163 172 if invalidate:
164 173 log.info('INVALIDATING CACHE FOR %s', repo_name)
165 174 region_invalidate(_get_repo, None, repo_name)
166 175
167 176 return _get_repo(repo_name)
168 177
@@ -1,593 +1,593 b''
1 1 <%inherit file="/base/base.html"/>
2 2
3 3 <%def name="title()">
4 4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
5 5 </%def>
6 6
7 7 <%def name="breadcrumbs_links()">
8 8 ${h.link_to(u'Home',h.url('/'))}
9 9 &raquo;
10 10 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
11 11 &raquo;
12 12 ${_('summary')}
13 13 </%def>
14 14
15 15 <%def name="page_nav()">
16 16 ${self.menu('summary')}
17 17 </%def>
18 18
19 19 <%def name="main()">
20 20 <script type="text/javascript">
21 21 var E = YAHOO.util.Event;
22 22 var D = YAHOO.util.Dom;
23 23
24 24 E.onDOMReady(function(e){
25 25 id = 'clone_url';
26 26 E.addListener(id,'click',function(e){
27 27 D.get('clone_url').select();
28 28 })
29 29 })
30 30 </script>
31 31 <div class="box box-left">
32 32 <!-- box / title -->
33 33 <div class="title">
34 34 ${self.breadcrumbs()}
35 35 </div>
36 36 <!-- end box / title -->
37 37 <div class="form">
38 38 <div class="fields">
39 39
40 40 <div class="field">
41 41 <div class="label">
42 42 <label>${_('Name')}:</label>
43 43 </div>
44 44 <div class="input-short">
45 45 %if c.repo_info.dbrepo.repo_type =='hg':
46 46 <img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="/images/icons/hgicon.png"/>
47 47 %endif
48 48 %if c.repo_info.dbrepo.repo_type =='git':
49 49 <img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="/images/icons/giticon.png"/>
50 50 %endif
51 51
52 52 %if c.repo_info.dbrepo.private:
53 53 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="/images/icons/lock.png"/>
54 54 %else:
55 55 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="/images/icons/lock_open.png"/>
56 56 %endif
57 57 <span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${c.repo_info.name}</span>
58 58 <br/>
59 59 %if c.repo_info.dbrepo.fork:
60 60 <span style="margin-top:5px">
61 61 <a href="${h.url('summary_home',repo_name=c.repo_info.dbrepo.fork.repo_name)}">
62 62 <img class="icon" alt="${_('public')}"
63 63 title="${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}"
64 64 src="/images/icons/arrow_divide.png"/>
65 65 ${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}
66 66 </a>
67 67 </span>
68 68 %endif
69 69 </div>
70 70 </div>
71 71
72 72
73 73 <div class="field">
74 74 <div class="label">
75 75 <label>${_('Description')}:</label>
76 76 </div>
77 77 <div class="input-short">
78 ${c.repo_info.description}
78 ${c.repo_info.dbrepo.description}
79 79 </div>
80 80 </div>
81 81
82 82
83 83 <div class="field">
84 84 <div class="label">
85 85 <label>${_('Contact')}:</label>
86 86 </div>
87 87 <div class="input-short">
88 88 <div class="gravatar">
89 89 <img alt="gravatar" src="${h.gravatar_url(c.repo_info.dbrepo.user.email)}"/>
90 90 </div>
91 91 ${_('Username')}: ${c.repo_info.dbrepo.user.username}<br/>
92 92 ${_('Name')}: ${c.repo_info.dbrepo.user.name} ${c.repo_info.dbrepo.user.lastname}<br/>
93 93 ${_('Email')}: <a href="mailto:${c.repo_info.dbrepo.user.email}">${c.repo_info.dbrepo.user.email}</a>
94 94 </div>
95 95 </div>
96 96
97 97 <div class="field">
98 98 <div class="label">
99 99 <label>${_('Last change')}:</label>
100 100 </div>
101 101 <div class="input-short">
102 102 ${h.age(c.repo_info.last_change)} - ${c.repo_info.last_change}
103 103 ${_('by')} ${h.get_changeset_safe(c.repo_info,'tip').author}
104 104
105 105 </div>
106 106 </div>
107 107
108 108 <div class="field">
109 109 <div class="label">
110 110 <label>${_('Clone url')}:</label>
111 111 </div>
112 112 <div class="input-short">
113 113 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
114 114 </div>
115 115 </div>
116 116
117 117 <div class="field">
118 118 <div class="label">
119 119 <label>${_('Trending languages')}:</label>
120 120 </div>
121 121 <div class="input-short">
122 122 <div id="lang_stats">
123 123
124 124 </div>
125 125 <script type="text/javascript">
126 126 var data = ${c.trending_languages|n};
127 127 var total = 0;
128 128 var no_data = true;
129 129 for (k in data){
130 130 total += data[k];
131 131 no_data = false;
132 132 }
133 133 var tbl = document.createElement('table');
134 134 tbl.setAttribute('class','trending_language_tbl');
135 135 for (k in data){
136 136 var tr = document.createElement('tr');
137 137 var percentage = Math.round((data[k]/total*100),2);
138 138 var value = data[k];
139 139 var td1 = document.createElement('td');
140 140 td1.width=150;
141 141 var trending_language_label = document.createElement('div');
142 142 trending_language_label.innerHTML = k;
143 143 td1.appendChild(trending_language_label);
144 144
145 145 var td2 = document.createElement('td');
146 146 var trending_language = document.createElement('div');
147 147 trending_language.title = k;
148 148 trending_language.innerHTML = "<b>"+percentage+"% "+value+" ${_('files')}</b>";
149 149 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
150 150 trending_language.style.width=percentage+"%";
151 151 td2.appendChild(trending_language);
152 152
153 153 tr.appendChild(td1);
154 154 tr.appendChild(td2);
155 155 tbl.appendChild(tr);
156 156
157 157 }
158 158 if(no_data){
159 159 var tr = document.createElement('tr');
160 160 var td1 = document.createElement('td');
161 161 td1.innerHTML = "${_('No data loaded yet')}";
162 162 tr.appendChild(td1);
163 163 tbl.appendChild(tr);
164 164 }
165 165 YAHOO.util.Dom.get('lang_stats').appendChild(tbl);
166 166 </script>
167 167
168 168 </div>
169 169 </div>
170 170
171 171 <div class="field">
172 172 <div class="label">
173 173 <label>${_('Download')}:</label>
174 174 </div>
175 175 <div class="input-short">
176 176 %for cnt,archive in enumerate(c.repo_info._get_archives()):
177 177 %if cnt >=1:
178 178 |
179 179 %endif
180 180 ${h.link_to(c.repo_info.name+'.'+archive['type'],
181 181 h.url('files_archive_home',repo_name=c.repo_info.name,
182 182 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
183 183 %endfor
184 184 </div>
185 185 </div>
186 186
187 187 <div class="field">
188 188 <div class="label">
189 189 <label>${_('Feeds')}:</label>
190 190 </div>
191 191 <div class="input-short">
192 192 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
193 193 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
194 194 </div>
195 195 </div>
196 196 </div>
197 197 </div>
198 198 </div>
199 199
200 200 <div class="box box-right" style="min-height:455px">
201 201 <!-- box / title -->
202 202 <div class="title">
203 203 <h5>${_('Commit activity by day / author')}</h5>
204 204 </div>
205 205
206 206 <div class="table">
207 207 <div id="commit_history" style="width:460px;height:300px;float:left"></div>
208 208 <div style="clear: both;height: 10px"></div>
209 209 <div id="overview" style="width:460px;height:100px;float:left"></div>
210 210
211 211 <div id="legend_data" style="clear:both;margin-top:10px;">
212 212 <div id="legend_container"></div>
213 213 <div id="legend_choices">
214 214 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
215 215 </div>
216 216 </div>
217 217 <script type="text/javascript">
218 218 /**
219 219 * Plots summary graph
220 220 *
221 221 * @class SummaryPlot
222 222 * @param {from} initial from for detailed graph
223 223 * @param {to} initial to for detailed graph
224 224 * @param {dataset}
225 225 * @param {overview_dataset}
226 226 */
227 227 function SummaryPlot(from,to,dataset,overview_dataset) {
228 228 var initial_ranges = {
229 229 "xaxis":{
230 230 "from":from,
231 231 "to":to,
232 232 },
233 233 };
234 234 var dataset = dataset;
235 235 var overview_dataset = [overview_dataset];
236 236 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
237 237 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
238 238 var plotContainer = YAHOO.util.Dom.get('commit_history');
239 239 var overviewContainer = YAHOO.util.Dom.get('overview');
240 240
241 241 var plot_options = {
242 242 bars: {show:true,align:'center',lineWidth:4},
243 243 legend: {show:true, container:"legend_container"},
244 244 points: {show:true,radius:0,fill:false},
245 245 yaxis: {tickDecimals:0,},
246 246 xaxis: {
247 247 mode: "time",
248 248 timeformat: "%d/%m",
249 249 min:from,
250 250 max:to,
251 251 },
252 252 grid: {
253 253 hoverable: true,
254 254 clickable: true,
255 255 autoHighlight:true,
256 256 color: "#999"
257 257 },
258 258 //selection: {mode: "x"}
259 259 };
260 260 var overview_options = {
261 261 legend:{show:false},
262 262 bars: {show:true,barWidth: 2,},
263 263 shadowSize: 0,
264 264 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
265 265 yaxis: {ticks: 3, min: 0,},
266 266 grid: {color: "#999",},
267 267 selection: {mode: "x"}
268 268 };
269 269
270 270 /**
271 271 *get dummy data needed in few places
272 272 */
273 273 function getDummyData(label){
274 274 return {"label":label,
275 275 "data":[{"time":0,
276 276 "commits":0,
277 277 "added":0,
278 278 "changed":0,
279 279 "removed":0,
280 280 }],
281 281 "schema":["commits"],
282 282 "color":'#ffffff',
283 283 }
284 284 }
285 285
286 286 /**
287 287 * generate checkboxes accordindly to data
288 288 * @param keys
289 289 * @returns
290 290 */
291 291 function generateCheckboxes(data) {
292 292 //append checkboxes
293 293 var i = 0;
294 294 choiceContainerTable.innerHTML = '';
295 295 for(var pos in data) {
296 296
297 297 data[pos].color = i;
298 298 i++;
299 299 if(data[pos].label != ''){
300 300 choiceContainerTable.innerHTML += '<tr><td>'+
301 301 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
302 302 +data[pos].label+
303 303 '</td></tr>';
304 304 }
305 305 }
306 306 }
307 307
308 308 /**
309 309 * ToolTip show
310 310 */
311 311 function showTooltip(x, y, contents) {
312 312 var div=document.getElementById('tooltip');
313 313 if(!div) {
314 314 div = document.createElement('div');
315 315 div.id="tooltip";
316 316 div.style.position="absolute";
317 317 div.style.border='1px solid #fdd';
318 318 div.style.padding='2px';
319 319 div.style.backgroundColor='#fee';
320 320 document.body.appendChild(div);
321 321 }
322 322 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
323 323 div.innerHTML = contents;
324 324 div.style.top=(y + 5) + "px";
325 325 div.style.left=(x + 5) + "px";
326 326
327 327 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
328 328 anim.animate();
329 329 }
330 330
331 331 /**
332 332 * This function will detect if selected period has some changesets for this user
333 333 if it does this data is then pushed for displaying
334 334 Additionally it will only display users that are selected by the checkbox
335 335 */
336 336 function getDataAccordingToRanges(ranges) {
337 337
338 338 var data = [];
339 339 var keys = [];
340 340 for(var key in dataset){
341 341 var push = false;
342 342 //method1 slow !!
343 343 ///*
344 344 for(var ds in dataset[key].data){
345 345 commit_data = dataset[key].data[ds];
346 346 //console.log(key);
347 347 //console.log(new Date(commit_data.time*1000));
348 348 //console.log(new Date(ranges.xaxis.from*1000));
349 349 //console.log(new Date(ranges.xaxis.to*1000));
350 350 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
351 351 push = true;
352 352 break;
353 353 }
354 354 }
355 355 //*/
356 356 /*//method2 sorted commit data !!!
357 357 var first_commit = dataset[key].data[0].time;
358 358 var last_commit = dataset[key].data[dataset[key].data.length-1].time;
359 359
360 360 console.log(first_commit);
361 361 console.log(last_commit);
362 362
363 363 if (first_commit >= ranges.xaxis.from && last_commit <= ranges.xaxis.to){
364 364 push = true;
365 365 }
366 366 */
367 367 if(push){
368 368 data.push(dataset[key]);
369 369 }
370 370 }
371 371 if(data.length >= 1){
372 372 return data;
373 373 }
374 374 else{
375 375 //just return dummy data for graph to plot itself
376 376 return [getDummyData('')];
377 377 }
378 378
379 379 }
380 380
381 381 /**
382 382 * redraw using new checkbox data
383 383 */
384 384 function plotchoiced(e,args){
385 385 var cur_data = args[0];
386 386 var cur_ranges = args[1];
387 387
388 388 var new_data = [];
389 389 var inputs = choiceContainer.getElementsByTagName("input");
390 390
391 391 //show only checked labels
392 392 for(var i=0; i<inputs.length; i++) {
393 393 var checkbox_key = inputs[i].name;
394 394
395 395 if(inputs[i].checked){
396 396 for(var d in cur_data){
397 397 if(cur_data[d].label == checkbox_key){
398 398 new_data.push(cur_data[d]);
399 399 }
400 400 }
401 401 }
402 402 else{
403 403 //push dummy data to not hide the label
404 404 new_data.push(getDummyData(checkbox_key));
405 405 }
406 406 }
407 407
408 408 var new_options = YAHOO.lang.merge(plot_options, {
409 409 xaxis: {
410 410 min: cur_ranges.xaxis.from,
411 411 max: cur_ranges.xaxis.to,
412 412 mode:"time",
413 413 timeformat: "%d/%m",
414 414 }
415 415 });
416 416 if (!new_data){
417 417 new_data = [[0,1]];
418 418 }
419 419 // do the zooming
420 420 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
421 421
422 422 plot.subscribe("plotselected", plotselected);
423 423
424 424 //resubscribe plothover
425 425 plot.subscribe("plothover", plothover);
426 426
427 427 // don't fire event on the overview to prevent eternal loop
428 428 overview.setSelection(cur_ranges, true);
429 429
430 430 }
431 431
432 432 /**
433 433 * plot only selected items from overview
434 434 * @param ranges
435 435 * @returns
436 436 */
437 437 function plotselected(ranges,cur_data) {
438 438 //updates the data for new plot
439 439 data = getDataAccordingToRanges(ranges);
440 440 generateCheckboxes(data);
441 441
442 442 var new_options = YAHOO.lang.merge(plot_options, {
443 443 xaxis: {
444 444 min: ranges.xaxis.from,
445 445 max: ranges.xaxis.to,
446 446 mode:"time",
447 447 timeformat: "%d/%m",
448 448 }
449 449 });
450 450 // do the zooming
451 451 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
452 452
453 453 plot.subscribe("plotselected", plotselected);
454 454
455 455 //resubscribe plothover
456 456 plot.subscribe("plothover", plothover);
457 457
458 458 // don't fire event on the overview to prevent eternal loop
459 459 overview.setSelection(ranges, true);
460 460
461 461 //resubscribe choiced
462 462 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
463 463 }
464 464
465 465 var previousPoint = null;
466 466
467 467 function plothover(o) {
468 468 var pos = o.pos;
469 469 var item = o.item;
470 470
471 471 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
472 472 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
473 473 if (item) {
474 474 if (previousPoint != item.datapoint) {
475 475 previousPoint = item.datapoint;
476 476
477 477 var tooltip = YAHOO.util.Dom.get("tooltip");
478 478 if(tooltip) {
479 479 tooltip.parentNode.removeChild(tooltip);
480 480 }
481 481 var x = item.datapoint.x.toFixed(2);
482 482 var y = item.datapoint.y.toFixed(2);
483 483
484 484 if (!item.series.label){
485 485 item.series.label = 'commits';
486 486 }
487 487 var d = new Date(x*1000);
488 488 var fd = d.toDateString()
489 489 var nr_commits = parseInt(y);
490 490
491 491 var cur_data = dataset[item.series.label].data[item.dataIndex];
492 492 var added = cur_data.added;
493 493 var changed = cur_data.changed;
494 494 var removed = cur_data.removed;
495 495
496 496 var nr_commits_suffix = " ${_('commits')} ";
497 497 var added_suffix = " ${_('files added')} ";
498 498 var changed_suffix = " ${_('files changed')} ";
499 499 var removed_suffix = " ${_('files removed')} ";
500 500
501 501
502 502 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
503 503 if(added==1){added_suffix=" ${_('file added')} ";}
504 504 if(changed==1){changed_suffix=" ${_('file changed')} ";}
505 505 if(removed==1){removed_suffix=" ${_('file removed')} ";}
506 506
507 507 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
508 508 +'<br/>'+
509 509 nr_commits + nr_commits_suffix+'<br/>'+
510 510 added + added_suffix +'<br/>'+
511 511 changed + changed_suffix + '<br/>'+
512 512 removed + removed_suffix + '<br/>');
513 513 }
514 514 }
515 515 else {
516 516 var tooltip = YAHOO.util.Dom.get("tooltip");
517 517
518 518 if(tooltip) {
519 519 tooltip.parentNode.removeChild(tooltip);
520 520 }
521 521 previousPoint = null;
522 522 }
523 523 }
524 524
525 525 /**
526 526 * MAIN EXECUTION
527 527 */
528 528
529 529 var data = getDataAccordingToRanges(initial_ranges);
530 530 generateCheckboxes(data);
531 531
532 532 //main plot
533 533 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
534 534
535 535 //overview
536 536 var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options);
537 537
538 538 //show initial selection on overview
539 539 overview.setSelection(initial_ranges);
540 540
541 541 plot.subscribe("plotselected", plotselected);
542 542
543 543 overview.subscribe("plotselected", function (ranges) {
544 544 plot.setSelection(ranges);
545 545 });
546 546
547 547 plot.subscribe("plothover", plothover);
548 548
549 549 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
550 550 }
551 551 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
552 552 </script>
553 553
554 554 </div>
555 555 </div>
556 556
557 557 <div class="box">
558 558 <div class="title">
559 559 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
560 560 </div>
561 561 <div class="table">
562 562 <div id="shortlog_data">
563 563 <%include file='../shortlog/shortlog_data.html'/>
564 564 </div>
565 565 ##%if c.repo_changesets:
566 566 ## ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
567 567 ##%endif
568 568 </div>
569 569 </div>
570 570 <div class="box">
571 571 <div class="title">
572 572 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
573 573 </div>
574 574 <div class="table">
575 575 <%include file='../tags/tags_data.html'/>
576 576 %if c.repo_changesets:
577 577 ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
578 578 %endif
579 579 </div>
580 580 </div>
581 581 <div class="box">
582 582 <div class="title">
583 583 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
584 584 </div>
585 585 <div class="table">
586 586 <%include file='../branches/branches_data.html'/>
587 587 %if c.repo_changesets:
588 588 ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
589 589 %endif
590 590 </div>
591 591 </div>
592 592
593 593 </%def> No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now