Changeset - b50e79b4257a
[Not reviewed]
default
0 6 0
Marcin Kuzminski - 15 years ago 2010-09-28 21:53:52
marcin@python-works.com
fixes to pidlock, to not raise unneded execptions
few fixes in templating for empty repository to not show some labels, fixed tag/branch switcher
6 files changed with 30 insertions and 6 deletions:
0 comments (0 inline, 0 general)
pylons_app/lib/celerylib/tasks.py
Show inline comments
 
from celery.decorators import task
 
from celery.task.sets import subtask
 
from celeryconfig import PYLONS_CONFIG as config
 
from operator import itemgetter
 
from pylons.i18n.translation import _
 
from pylons_app.lib.celerylib import run_task, locked_task
 
from pylons_app.lib.helpers import person
 
from pylons_app.lib.smtp_mailer import SmtpMailer
 
from pylons_app.lib.utils import OrderedDict
 
from time import mktime
 
from vcs.backends.hg import MercurialRepository
 
import json
 
import traceback
 

	
 
__all__ = ['whoosh_index', 'get_commits_stats',
 
           'reset_user_password', 'send_email']
 

	
 
def get_session():
 
    from sqlalchemy import engine_from_config
 
    from sqlalchemy.orm import sessionmaker, scoped_session
 
    engine = engine_from_config(dict(config.items('app:main')), 'sqlalchemy.db1.')
 
    sa = scoped_session(sessionmaker(bind=engine))
 
    return sa
 

	
 
def get_hg_settings():
 
    from pylons_app.model.db import HgAppSettings
 
    try:
 
        sa = get_session()
 
        ret = sa.query(HgAppSettings).all()
 
    finally:
 
        sa.remove()
 
        
 
    if not ret:
 
        raise Exception('Could not get application settings !')
 
    settings = {}
 
    for each in ret:
 
        settings['hg_app_' + each.app_settings_name] = each.app_settings_value    
 
    
 
    return settings
 

	
 
def get_hg_ui_settings():
 
    from pylons_app.model.db import HgAppUi
 
    try:
 
        sa = get_session()
 
        ret = sa.query(HgAppUi).all()
 
    finally:
 
        sa.remove()
 
        
 
    if not ret:
 
        raise Exception('Could not get application ui settings !')
 
    settings = {}
 
    for each in ret:
 
        k = each.ui_key
 
        v = each.ui_value
 
        if k == '/':
 
            k = 'root_path'
 
        
 
        if k.find('.') != -1:
 
            k = k.replace('.', '_')
 
        
 
        if each.ui_section == 'hooks':
 
            v = each.ui_active
 
        
 
        settings[each.ui_section + '_' + k] = v  
 
    
 
    return settings   
 

	
 
@task
 
@locked_task
 
def whoosh_index(repo_location, full_index):
 
    log = whoosh_index.get_logger()
 
    from pylons_app.lib.indexers.daemon import WhooshIndexingDaemon
 
    WhooshIndexingDaemon(repo_location=repo_location).run(full_index=full_index)
 

	
 
@task
 
@locked_task
 
def get_commits_stats(repo_name, ts_min_y, ts_max_y):
 
    from pylons_app.model.db import Statistics, Repository
 
    log = get_commits_stats.get_logger()
 
    author_key_cleaner = lambda k: person(k).replace('"', "") #for js data compatibilty
 
    
 
    commits_by_day_author_aggregate = {}
 
    commits_by_day_aggregate = {}
 
    repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
 
    repo = MercurialRepository(repos_path + repo_name)
 

	
 
    skip_date_limit = True
 
    parse_limit = 350 #limit for single task changeset parsing
 
    parse_limit = 350 #limit for single task changeset parsing optimal for
 
    last_rev = 0
 
    last_cs = None
 
    timegetter = itemgetter('time')
 
    
 
    sa = get_session()
 
    
 
    dbrepo = sa.query(Repository)\
 
        .filter(Repository.repo_name == repo_name).scalar()
 
    cur_stats = sa.query(Statistics)\
 
        .filter(Statistics.repository == dbrepo).scalar()
 
    if cur_stats:
 
        last_rev = cur_stats.stat_on_revision
 
    if not repo.revisions:
 
        return True
 
    
 
    if last_rev == repo.revisions[-1] and len(repo.revisions) > 1:
 
        #pass silently without any work
 
        #pass silently without any work if we're not on first revision or current
 
        #state of parsing revision(from db marker) is the last revision
 
        return True
 
    
 
    if cur_stats:
 
        commits_by_day_aggregate = OrderedDict(
 
                                       json.loads(
 
                                        cur_stats.commit_activity_combined))
 
        commits_by_day_author_aggregate = json.loads(cur_stats.commit_activity)
 
    
 
    log.debug('starting parsing %s', parse_limit)
 
    for cnt, rev in enumerate(repo.revisions[last_rev:]):
 
        last_cs = cs = repo.get_changeset(rev)
 
        k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1],
 
                          cs.date.timetuple()[2])
 
        timetupple = [int(x) for x in k.split('-')]
 
        timetupple.extend([0 for _ in xrange(6)])
 
        k = mktime(timetupple)
 
        if commits_by_day_author_aggregate.has_key(author_key_cleaner(cs.author)):
 
            try:
 
                l = [timegetter(x) for x in commits_by_day_author_aggregate\
 
                        [author_key_cleaner(cs.author)]['data']]
 
                time_pos = l.index(k)
 
            except ValueError:
 
                time_pos = False
 
                
 
            if time_pos >= 0 and time_pos is not False:
 
                
 
                datadict = commits_by_day_author_aggregate\
 
                    [author_key_cleaner(cs.author)]['data'][time_pos]
 
                
 
                datadict["commits"] += 1
 
                datadict["added"] += len(cs.added)
 
                datadict["changed"] += len(cs.changed)
 
                datadict["removed"] += len(cs.removed)
 
                #print datadict
 
                
 
            else:
 
                #print 'ELSE !!!!'
 
                if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
 
                    
 
                    datadict = {"time":k,
 
                                "commits":1,
 
                                "added":len(cs.added),
 
                                "changed":len(cs.changed),
 
                                "removed":len(cs.removed),
 
                               }
 
                    commits_by_day_author_aggregate\
 
                        [author_key_cleaner(cs.author)]['data'].append(datadict)
 
                                        
 
        else:
 
            #print k, 'nokey ADDING'
 
            if k >= ts_min_y and k <= ts_max_y or skip_date_limit:
 
                commits_by_day_author_aggregate[author_key_cleaner(cs.author)] = {
 
                                    "label":author_key_cleaner(cs.author),
 
                                    "data":[{"time":k,
 
                                             "commits":1,
 
                                             "added":len(cs.added),
 
                                             "changed":len(cs.changed),
 
                                             "removed":len(cs.removed),
 
                                             }],
 
                                    "schema":["commits"],
 
                                    }               
 
    
 
#        #gather all data by day
 
        if commits_by_day_aggregate.has_key(k):
 
            commits_by_day_aggregate[k] += 1
 
        else:
 
            commits_by_day_aggregate[k] = 1
 
        
 
        if cnt >= parse_limit:
 
            #don't fetch to much data since we can freeze application
 
            break
 

	
 
    overview_data = []
 
    for k, v in commits_by_day_aggregate.items():
 
        overview_data.append([k, v])
 
    overview_data = sorted(overview_data, key=itemgetter(0))
 
        
 
    if not commits_by_day_author_aggregate:
 
        commits_by_day_author_aggregate[author_key_cleaner(repo.contact)] = {
 
            "label":author_key_cleaner(repo.contact),
 
            "data":[0, 1],
 
            "schema":["commits"],
 
        }
 

	
 
    stats = cur_stats if cur_stats else Statistics()
 
    stats.commit_activity = json.dumps(commits_by_day_author_aggregate)
 
    stats.commit_activity_combined = json.dumps(overview_data)
 

	
 
    log.debug('last revison %s', last_rev)
 
    leftovers = len(repo.revisions[last_rev:])
 
    log.debug('revisions to parse %s', leftovers)
 
    
 
    if last_rev == 0 or leftovers < parse_limit:    
 
        stats.languages = json.dumps(__get_codes_stats(repo_name))
 
        
 
    stats.repository = dbrepo
 
    stats.stat_on_revision = last_cs.revision
 
    
 
    try:
 
        sa.add(stats)
 
        sa.commit()    
 
    except:
 
        log.error(traceback.format_exc())
 
        sa.rollback()
 
        return False
 
    if len(repo.revisions) > 1:
 
        run_task(get_commits_stats, repo_name, ts_min_y, ts_max_y)
 
                            
 
    return True
 

	
 
@task
 
def reset_user_password(user_email):
 
    log = reset_user_password.get_logger()
 
    from pylons_app.lib import auth
 
    from pylons_app.model.db import User
 
    
 
    try:
 
        try:
 
            sa = get_session()
 
            user = sa.query(User).filter(User.email == user_email).scalar()
 
            new_passwd = auth.PasswordGenerator().gen_password(8,
 
                             auth.PasswordGenerator.ALPHABETS_BIG_SMALL)
 
            if user:
 
                user.password = auth.get_crypt_password(new_passwd)
 
                sa.add(user)
 
                sa.commit()
 
                log.info('change password for %s', user_email)
 
            if new_passwd is None:
 
                raise Exception('unable to generate new password')
 
            
 
        except:
 
            log.error(traceback.format_exc())
 
            sa.rollback()
 
        
 
        run_task(send_email, user_email,
 
                 "Your new hg-app password",
 
                 'Your new hg-app password:%s' % (new_passwd))
 
        log.info('send new password mail to %s', user_email)
 
        
 
        
 
    except:
 
        log.error('Failed to update user password')
 
        log.error(traceback.format_exc())
 
    return True
 

	
 
@task    
 
def send_email(recipients, subject, body):
 
    log = send_email.get_logger()
 
    email_config = dict(config.items('DEFAULT')) 
 
    mail_from = email_config.get('app_email_from')
 
    user = email_config.get('smtp_username')
 
    passwd = email_config.get('smtp_password')
 
    mail_server = email_config.get('smtp_server')
 
    mail_port = email_config.get('smtp_port')
 
    tls = email_config.get('smtp_use_tls')
 
    ssl = False
 
    
 
    try:
 
        m = SmtpMailer(mail_from, user, passwd, mail_server,
 
                       mail_port, ssl, tls)
 
        m.send(recipients, subject, body)  
 
    except:
 
        log.error('Mail sending failed')
 
        log.error(traceback.format_exc())
 
        return False
 
    return True
 

	
 
def __get_codes_stats(repo_name):
 
    LANGUAGES_EXTENSIONS = ['action', 'adp', 'ashx', 'asmx', 'aspx', 'asx', 'axd', 'c',
 
                    'cfg', 'cfm', 'cpp', 'cs', 'diff', 'do', 'el', 'erl',
 
                    'h', 'java', 'js', 'jsp', 'jspx', 'lisp',
 
                    'lua', 'm', 'mako', 'ml', 'pas', 'patch', 'php', 'php3',
 
                    'php4', 'phtml', 'pm', 'py', 'rb', 'rst', 's', 'sh',
 
                    'tpl', 'txt', 'vim', 'wss', 'xhtml', 'xml', 'xsl', 'xslt',
 
                    'yaws']
 
    repos_path = get_hg_ui_settings()['paths_root_path'].replace('*', '')
 
    repo = MercurialRepository(repos_path + repo_name)
 

	
 
    code_stats = {}
 
    for topnode, dirs, files in repo.walk('/', 'tip'):
 
        for f in files:
 
            k = f.mimetype
 
            if f.extension in LANGUAGES_EXTENSIONS:
 
                if code_stats.has_key(k):
 
                    code_stats[k] += 1
 
                else:
 
                    code_stats[k] = 1
 
                    
 
    return code_stats or {}
 

	
 

	
 
            
pylons_app/lib/pidlock.py
Show inline comments
 
import os, time
 
import sys
 
from warnings import warn
 
from multiprocessing.util import Finalize
 
import errno
 

	
 
class LockHeld(Exception):pass
 

	
 

	
 
class DaemonLock(object):
 
    """daemon locking
 
    USAGE:
 
    try:
 
        l = DaemonLock(desc='test lock')
 
        main()
 
        l.release()
 
    except LockHeld:
 
        sys.exit(1)
 
    """
 

	
 
    def __init__(self, file=None, callbackfn=None,
 
                 desc='daemon lock', debug=False):
 

	
 
        self.pidfile = file if file else os.path.join(os.path.dirname(__file__),
 
                                                      'running.lock')
 
        self.callbackfn = callbackfn
 
        self.desc = desc
 
        self.debug = debug
 
        self.held = False
 
        #run the lock automatically !
 
        self.lock()
 
        self._finalize = Finalize(self, DaemonLock._on_finalize,
 
                                    args=(self, debug), exitpriority=10)
 

	
 
    @staticmethod
 
    def _on_finalize(lock, debug):
 
        if lock.held:
 
            if debug:
 
                print 'leck held finilazing and running lock.release()'
 
            lock.release()
 

	
 

	
 
    def lock(self):
 
        """locking function, if lock is present it will raise LockHeld exception
 
        """
 
        lockname = '%s' % (os.getpid())
 
        if self.debug:
 
            print 'running lock'
 
        self.trylock()
 
        self.makelock(lockname, self.pidfile)
 
        return True
 

	
 
    def trylock(self):
 
        running_pid = False
 
        if self.debug:
 
            print 'checking for already running process'
 
        try:
 
            pidfile = open(self.pidfile, "r")
 
            pidfile.seek(0)
 
            running_pid = int(pidfile.readline())
 
            
 
            pidfile.close()
 
            
 
            if self.debug:
 
                print 'lock file present running_pid: %s, checking for execution'\
 
                % running_pid
 
            # Now we check the PID from lock file matches to the current
 
            # process PID
 
            if running_pid:
 
                try:
 
                    os.kill(running_pid, 0)
 
                except OSError, exc:
 
                    if exc.errno in (errno.ESRCH, errno.EPERM):
 
                        print "Lock File is there but the program is not running"
 
                        print "Removing lock file for the: %s" % running_pid                        
 
                        self.release()
 
                    else:
 
                    raise
 
                else:
 
                    print "You already have an instance of the program running"
 
                    print "It is running as process %s" % running_pid                    
 
                    raise LockHeld()
 
                         
 
        except IOError, e:
 
            if e.errno != 2:
 
                raise
 

	
 
    def release(self):
 
        """releases the pid by removing the pidfile
 
        """
 
        if self.debug:
 
            print 'trying to release the pidlock'
 
            
 
        if self.callbackfn:
 
            #execute callback function on release
 
            if self.debug:
 
                print 'executing callback function %s' % self.callbackfn
 
            self.callbackfn()
 
        try:
 
            if self.debug:
 
                print 'removing pidfile %s' % self.pidfile
 
            os.remove(self.pidfile)
 
            self.held = False
 
        except OSError, e:
 
            if self.debug:
 
                print 'removing pidfile failed %s' % e
 
            pass
 

	
 
    def makelock(self, lockname, pidfile):
 
        """
 
        this function will make an actual lock
 
        @param lockname: acctual pid of file
 
        @param pidfile: the file to write the pid in
 
        """
 
        if self.debug:
 
            print 'creating a file %s and pid: %s' % (pidfile, lockname)
 
        pidfile = open(self.pidfile, "wb")
 
        pidfile.write(lockname)
 
        pidfile.close
 
        self.held = True
pylons_app/templates/base/base.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml" id="mainhtml">
 
<head>
 
    <title>${next.title()}</title>
 
    <link rel="icon" href="/images/hgicon.png" type="image/png" />
 
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 
    <meta name="robots" content="index, nofollow"/>
 
    <!-- stylesheets -->
 
    ${self.css()}
 
    <!-- scripts -->
 
    ${self.js()}
 
</head>
 
<body>
 
    <!-- header -->
 
    <div id="header">
 
        <!-- user -->
 
        <ul id="logged-user">
 
            <li class="first">
 
	            <div class="gravatar">
 
	            	<img alt="gravatar" src="${h.gravatar_url(c.hg_app_user.email,24)}" />
 
	            </div>
 
	            <div class="account">
 
	            	${h.link_to('%s %s'%(c.hg_app_user.name,c.hg_app_user.lastname),h.url('admin_settings_my_account'))}<br/>
 
	            	${h.link_to(c.hg_app_user.username,h.url('admin_settings_my_account'))}
 
	            </div>	
 
            </li>
 
            <li class="last highlight">${h.link_to(u'Logout',h.url('logout_home'))}</li>
 
        </ul>
 
        <!-- end user -->
 
        <div id="header-inner">
 
            <div id="home">
 
                <a href="${h.url('hg_home')}"></a>
 
            </div>
 
            <!-- logo -->
 
            <div id="logo">
 
                <h1><a href="${h.url('hg_home')}">${c.hg_app_name}</a></h1>
 
            </div>
 
            <!-- end logo -->
 
            <!-- quick menu -->
 
            ${self.page_nav()}
 
            <!-- end quick -->
 
            <div class="corner tl"></div>
 
            <div class="corner tr"></div>
 
        </div>
 
    </div>     
 
    <!-- end header -->
 
    
 
	<!-- CONTENT -->
 
	<div id="content"> 
 
        <div class="flash_msg">
 
            <% messages = h.flash.pop_messages() %>
 
            % if messages:
 
            <ul id="flash-messages">
 
                % for message in messages:
 
                <li class="${message.category}_msg">${message}</li>
 
                % endfor
 
            </ul>
 
            % endif
 
        </div>	    
 
	    <div id="main"> 
 
	        ${next.main()}
 
	    </div>
 
	</div> 
 
    <!-- END CONTENT -->
 

	
 
	<!-- footer -->
 
	<div id="footer">
 
	    <p>Hg App ${c.hg_app_version} &copy; 2010 by Marcin Kuzminski</p>
 
        <script type="text/javascript">${h.tooltip.activate()}</script>	    
 
	</div>
 
	<!-- end footer -->
 
</body>
 

	
 
</html>
 

	
 
### MAKO DEFS ### 
 
<%def name="page_nav()">
 
	${self.menu()}
 
</%def>
 

	
 
<%def name="menu(current=None)">
 
		<% 
 
		def is_current(selected):
 
			if selected == current:
 
				return h.literal('class="current"')
 
		%>
 
		%if current not in ['home','admin']:           		
 
		   ##REGULAR MENU            
 
	        <ul id="quick">
 
				<!-- repo switcher -->
 
				<li>
 
					<a id="repo_switcher" title="${_('Switch repository')}" href="#">
 
                    <span class="icon">
 
                        <img src="/images/icons/database.png" alt="${_('Products')}" />
 
                    </span>
 
                    <span>&darr;</span>					
 
					</a>
 
					<ul class="repo_switcher">
 
                        %for repo,private in c.repo_switcher_list:
 
                          %if private:
 
                             <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="private_repo")}</li>
 
                          %else:
 
                             <li>${h.link_to(repo,h.url('summary_home',repo_name=repo),class_="public_repo")}</li>
 
                          %endif  
 
                        %endfor					
 
					</ul>			
 
				</li>
 
				
 
	            <li ${is_current('summary')}>
 
	               <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
 
	               <span class="icon">
 
	                   <img src="/images/icons/clipboard_16.png" alt="${_('Summary')}" />
 
	               </span>
 
	               <span>${_('Summary')}</span>                 
 
	               </a>	            
 
	            </li>
 
                <li ${is_current('shortlog')}>
 
                   <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
 
                   <span class="icon">
 
                       <img src="/images/icons/application_double.png" alt="${_('Shortlog')}" />
 
                   </span>
 
                   <span>${_('Shortlog')}</span>                 
 
                   </a>             
 
                </li>	            
 
                <li ${is_current('changelog')}>
 
                   <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
 
                   <span class="icon">
 
                       <img src="/images/icons/time.png" alt="${_('Changelog')}" />
 
                   </span>
 
                   <span>${_('Changelog')}</span>                 
 
                   </a>             
 
                </li>   	
 
                
 
                <li ${is_current('switch_to')}>
 
                   <a title="${_('Switch to')}" href="#">
 
                   <span class="icon">
 
                       <img src="/images/icons/arrow_switch.png" alt="${_('Switch to')}" />
 
                   </span>
 
                   <span>${_('Switch to')}</span>                 
 
                   </a>    
 
                    <ul>
 
                        <li>
 
                            ${h.link_to(_('branches'),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
 
                            <ul>
 
                            %if c.repository_branches.values():
 
						        %for cnt,branch in enumerate(c.repository_branches.items()):
 
						            <li>${h.link_to('%s - %s' % (branch[0],branch[1]),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
 
						        %endfor
 
						    %else:
 
						    	<li>${h.link_to(_('There are no branches yet'),'#')}</li>
 
						    %endif
 
                            </ul>                        
 
                        </li>
 
                        <li>
 
                            ${h.link_to(_('tags'),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
 
                            <ul>
 
                            %if c.repository_tags.values():
 
                                %for cnt,tag in enumerate(c.repository_tags.items()):
 
                                 <li>${h.link_to('%s - %s' % (tag[0],tag[1]),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
 
                                %endfor
 
                            %else:
 
                            	<li>${h.link_to(_('There are no tags yet'),'#')}</li>
 
                            %endif
 
                            </ul>                        
 
                        </li>                        
 
                    </ul>
 
                </li>
 
                <li ${is_current('files')}>
 
                   <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
 
                   <span class="icon">
 
                       <img src="/images/icons/file.png" alt="${_('Files')}" />
 
                   </span>
 
                   <span>${_('Files')}</span>                 
 
                   </a>             
 
                </li>                            
 
				%if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
 
                <li ${is_current('settings')}>
 
                   <a title="${_('Settings')}" href="${h.url('repo_settings_home',repo_name=c.repo_name)}">
 
                   <span class="icon">
 
                       <img src="/images/icons/cog_edit.png" alt="${_('Settings')}" />
 
                   </span>
 
                   <span>${_('Settings')}</span>                 
 
                   </a>             
 
                </li>				
 
				%endif					        
 
	        </ul>
 
		%else:
 
		    ##ROOT MENU
 
            <ul id="quick">
 
                <li>
 
                    <a title="${_('Home')}"  href="${h.url('hg_home')}">
 
                    <span class="icon">
 
                        <img src="/images/icons/home_16.png" alt="${_('Home')}" />
 
                    </span>
 
                    <span>${_('Home')}</span>                 
 
                    </a>        
 
                </li>
 
                
 
                <li>
 
                    <a title="${_('Search')}"  href="${h.url('search')}">
 
                    <span class="icon">
 
                        <img src="/images/icons/search_16.png" alt="${_('Search')}" />
 
                    </span>
 
                    <span>${_('Search')}</span>                 
 
                    </a>        
 
                </li>
 
                
 
				%if h.HasPermissionAll('hg.admin')('access admin main page'):
 
                <li ${is_current('admin')}>
 
                   <a title="${_('Admin')}" href="${h.url('admin_home')}">
 
                   <span class="icon">
 
                       <img src="/images/icons/cog_edit.png" alt="${_('Admin')}" />
 
                   </span>
 
                   <span>${_('Admin')}</span>                 
 
                   </a>    
 
				    <ul>
 
				        <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
 
				        <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
 
				        <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
 
				        <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
 
				        <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>        
 
				    </ul>
 
                </li>
 
				%endif
 
				
 
			</ul>
 
		%endif    
 
</%def>
 

	
 

	
 
<%def name="css()">
 
<link rel="stylesheet" type="text/css" href="/css/reset.css" />
 
<link rel="stylesheet" type="text/css" href="/css/style.css" media="screen" />
 
<link id="color" rel="stylesheet" type="text/css" href="/css/colors/blue.css" />
 
<link rel="stylesheet" type="text/css" href="/css/pygments.css"  />
 
<link rel="stylesheet" type="text/css" href="/css/diff.css"  />
 
</%def>
 

	
 
<%def name="js()">
 
##<script type="text/javascript" src="/js/yui/utilities/utilities.js"></script>
 
##<script type="text/javascript" src="/js/yui/container/container.js"></script>
 
##<script type="text/javascript" src="/js/yui/datasource/datasource.js"></script>
 
##<script type="text/javascript" src="/js/yui/autocomplete/autocomplete.js"></script>
 

	
 
<script type="text/javascript" src="/js/yui2.js"></script>
 
<!--[if IE]><script language="javascript" type="text/javascript" src="/js/excanvas.min.js"></script><![endif]-->
 
<script type="text/javascript" src="/js/yui.flot.js"></script>
 
</%def>
 

	
 
<%def name="breadcrumbs()">
 
    <div class="breadcrumbs">
 
    ${self.breadcrumbs_links()}
 
    </div>
 
</%def>
 
\ No newline at end of file
pylons_app/templates/index.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="base/base.html"/>
 
<%def name="title()">
 
    ${c.hg_app_name}
 
</%def>
 
<%def name="breadcrumbs()">
 
	${c.hg_app_name}
 
</%def>
 
<%def name="page_nav()">
 
	${self.menu('home')}
 
</%def>
 
<%def name="main()">
 
	<%def name="get_sort(name)">
 
		<%name_slug = name.lower().replace(' ','_') %>
 
		
 
		%if name_slug == c.sort_slug:
 
		  %if c.sort_by.startswith('-'):
 
		    <a href="?sort=${name_slug}">${name}&uarr;</a>
 
		  %else:
 
		    <a href="?sort=-${name_slug}">${name}&darr;</a>
 
		  %endif:
 
		%else:
 
		    <a href="?sort=${name_slug}">${name}</a>
 
		%endif
 
	</%def>
 
	
 
    <div class="box">
 
	    <!-- box / title -->
 
	    <div class="title">
 
	        <h5>${_('Dashboard')}</h5>
 
	        %if h.HasPermissionAny('hg.admin','hg.create.repository')():
 
	        <ul class="links">
 
	          <li>
 
	            <span>${h.link_to(u'ADD NEW REPOSITORY',h.url('admin_settings_create_repository'),class_="add_icon")}</span>
 
	          </li>          
 
	        </ul>  	        
 
	        %endif
 
	    </div>
 
	    <!-- end box / title -->
 
        <div class="table">
 
                    <table>
 
            <thead>
 
	            <tr>
 
			        <th class="left">${get_sort(_('Name'))}</th>
 
			        <th class="left">${get_sort(_('Description'))}</th>
 
			        <th class="left">${get_sort(_('Last change'))}</th>
 
			        <th class="left">${get_sort(_('Tip'))}</th>
 
			        <th class="left">${get_sort(_('Contact'))}</th>
 
			        <th class="left">${_('RSS')}</th>
 
			        <th class="left">${_('Atom')}</th>
 
	            </tr>
 
            </thead>
 
                        <tbody>
 
					    %for cnt,repo in enumerate(c.repos_list):
 
					        %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'):
 
					        <tr class="parity${cnt%2}">
 
					            <td>
 
					             %if repo['repo'].dbrepo.private:
 
					                <img class="icon" alt="${_('private')}" src="/images/icons/lock.png"/>
 
					             %else:
 
					                <img class="icon" alt="${_('public')}" src="/images/icons/lock_open.png"/>
 
					             %endif  
 
					            ${h.link_to(repo['name'],
 
					                h.url('summary_home',repo_name=repo['name']))}</td>
 
					            <td title="${repo['description']}">${h.truncate(repo['description'],60)}</td>
 
					            <td>${h.age(repo['last_change'])}</td>
 
					            <td>${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']),
 
					            <td>
 
					            	%if repo['rev']>=0:
 
					            	${h.link_to('r%s:%s' % (repo['rev'],repo['tip']),
 
					                h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']),
 
					                class_="tooltip",
 
					                tooltip_title=h.tooltip(repo['last_msg']))}</td>
 
					                tooltip_title=h.tooltip(repo['last_msg']))}
 
					            	%else:
 
					            		${_('No changesets yet')}
 
					            	%endif    
 
					            </td>
 
					            <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
 
					            <td>
 
					                <a title="${_('Subscribe to %s rss feed')%repo['name']}" class="rss_icon"  href="${h.url('rss_feed_home',repo_name=repo['name'])}"></a>
 
					            </td>        
 
					            <td>
 
					                <a title="${_('Subscribe to %s atom feed')%repo['name']}"  class="atom_icon" href="${h.url('atom_feed_home',repo_name=repo['name'])}"></a>
 
					            </td>
 
					        </tr>
 
					        %endif
 
					    %endfor
 
                        </tbody>
 
                    </table>
 
            </div>
 
    </div>	
 
</%def>    
pylons_app/templates/shortlog/shortlog_data.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
% if c.repo_changesets:
 
<table>
 
	<tr>
 
		<th class="left">${_('date')}</th>
 
		<th class="left">${_('author')}</th>
 
		<th class="left">${_('revision')}</th>
 
		<th class="left">${_('commit message')}</th>
 
		<th class="left">${_('branch')}</th>
 
		<th class="left">${_('tags')}</th>
 
		<th class="left">${_('links')}</th>
 
		
 
	</tr>
 
%for cnt,cs in enumerate(c.repo_changesets):
 
	<tr class="parity${cnt%2}">
 
		<td>${h.age(cs._ctx.date())} - ${h.rfc822date_notz(cs._ctx.date())} </td>
 
		<td title="${cs.author}">${h.person(cs.author)}</td>
 
		<td>r${cs.revision}:${cs.raw_id}</td>
 
		<td>
 
			${h.link_to(h.truncate(cs.message,60),
 
			h.url('changeset_home',repo_name=c.repo_name,revision=cs._short),
 
			title=cs.message)}
 
		</td>
 
		<td>
 
			<span class="logtags">
 
				<span class="branchtag">${cs.branch}</span>
 
			</span>
 
		</td>
 
		<td>
 
			<span class="logtags">
 
				%for tag in cs.tags:
 
					<span class="tagtag">${tag}</span>
 
				%endfor
 
			</span>
 
		</td>
 
		<td class="nowrap">
 
		${h.link_to(_('changeset'),h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
 
		|
 
		${h.link_to(_('files'),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
 
		</td>
 
	</tr>	
 
%endfor
 

	
 
</table>
 

	
 
<script type="text/javascript">
 
  var data_div = 'shortlog_data';
 
  YAHOO.util.Event.onDOMReady(function(){
 
    YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
 
            YAHOO.util.Dom.setStyle('shortlog_data','opacity','0.3');});});
 
</script>
 

	
 
<div class="pagination-wh pagination-left">
 
${c.repo_changesets.pager('$link_previous ~2~ $link_next',     
 
onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
 
success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
 
YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
 
        YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});       
 
YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
 
</div>
 
%else:
 
    ${_('There are no commits yet')}
 
    ${_('There are no changes yet')}
 
%endif
pylons_app/templates/summary/summary.html
Show inline comments
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${_('Mercurial Repository Overview')}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(u'Home',h.url('/'))}
 
    &raquo; 
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    ${_('summary')}
 
</%def>
 

	
 
<%def name="page_nav()">
 
	${self.menu('summary')}    
 
</%def>
 

	
 
<%def name="main()">
 
<script type="text/javascript">
 
var E = YAHOO.util.Event;
 
var D = YAHOO.util.Dom;
 

	
 
E.onDOMReady(function(e){
 
    id = 'clone_url';
 
    E.addListener(id,'click',function(e){
 
        D.get('clone_url').select();
 
    })
 
})
 
</script>
 
<div class="box box-left">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <!-- end box / title -->
 
	<div class="form">
 
	  <div class="fields">
 
		 
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Name')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			      <span style="font-size: 1.6em;font-weight: bold">${c.repo_info.name}</span>
 
			  </div>
 
			 </div>
 
			
 
			
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Description')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			      ${c.repo_info.description}
 
			  </div>
 
			 </div>
 
			
 
			
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Contact')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			  	<div class="gravatar">
 
			  		<img alt="gravatar" src="${h.gravatar_url(c.repo_info.dbrepo.user.email)}"/>
 
			  	</div>
 
			  		${_('Username')}: ${c.repo_info.dbrepo.user.username}<br/>
 
			  		${_('Name')}: ${c.repo_info.dbrepo.user.name} ${c.repo_info.dbrepo.user.lastname}<br/>
 
			  		${_('Email')}: <a href="mailto:${c.repo_info.dbrepo.user.email}">${c.repo_info.dbrepo.user.email}</a>
 
			  </div>
 
			 </div>
 
			
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Last change')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			      ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)} 
 
			      ${_('by')} ${h.get_changeset_safe(c.repo_info,'tip').author} 
 
			      
 
			  </div>
 
			 </div>
 
			
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Clone url')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			      <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
 
			  </div>
 
			 </div>
 
			 
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Trending languages')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
			    <div id="lang_stats">
 
			    
 
			    </div> 			  
 
			  	<script type="text/javascript">
 
			  		var data = ${c.trending_languages|n};
 
			  		var total = 0;
 
			  		var no_data = true;
 
			  		for (k in data){
 
			  		    total += data[k];
 
			  		    no_data = false;
 
			  		} 
 
					var tbl = document.createElement('table');
 
					tbl.setAttribute('class','trending_language_tbl');
 
			  		for (k in data){
 
				  		var tr = document.createElement('tr');
 
				  		var percentage = Math.round((data[k]/total*100),2);
 
						var value = data[k];
 
				  		var td1 = document.createElement('td');
 
				  		td1.width=150;
 
				  		var trending_language_label = document.createElement('div');
 
				  		trending_language_label.innerHTML = k;
 
				  		td1.appendChild(trending_language_label);
 

	
 
				  		var td2 = document.createElement('td');
 
			  		    var trending_language = document.createElement('div');
 
			  		    trending_language.title = k;
 
			  		    trending_language.innerHTML = "<b>"+value+" ${_('files')} - "+percentage+" %</b>";
 
			  		    trending_language.setAttribute("class", 'trending_language');
 
			  		    trending_language.style.width=percentage+"%";
 
						td2.appendChild(trending_language);
 
						
 
						tr.appendChild(td1);
 
						tr.appendChild(td2);
 
			  		    tbl.appendChild(tr);
 
 				  		//YAHOO.util.Dom.get('lang_stats').appendChild(trending_language_label);
 
			  		    
 
			  		}
 
			  		if(no_data){
 
			  			var tr = document.createElement('tr');
 
			  			var td1 = document.createElement('td');
 
			  			td1.innerHTML = "${_('No data loaded yet...')}";
 
			  			td1.innerHTML = "${_('No data loaded yet')}";
 
			  			tr.appendChild(td1);
 
			  			tbl.appendChild(tr);
 
					}
 
			  		YAHOO.util.Dom.get('lang_stats').appendChild(tbl);
 
			  	</script>
 
 
 
			  </div>
 
			 </div>
 
			 			
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Download')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
		        %for cnt,archive in enumerate(c.repo_info._get_archives()):
 
		             %if cnt >=1:
 
		             |
 
		             %endif
 
		             ${h.link_to(c.repo_info.name+'.'+archive['type'],
 
		                h.url('files_archive_home',repo_name=c.repo_info.name,
 
		                revision='tip',fileformat=archive['extension']),class_="archive_icon")}
 
		        %endfor
 
			  </div>
 
			 </div>
 
			 
 
			 <div class="field">
 
			  <div class="label">
 
			      <label>${_('Feeds')}:</label>
 
			  </div>
 
			  <div class="input-short">
 
	            ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
 
	            ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
 
			  </div>
 
			 </div>				 			 			 
 
	  </div>		 
 
	</div>				
 
</div>
 
        
 
<div class="box box-right"  style="min-height:455px">
 
    <!-- box / title -->
 
    <div class="title">
 
        <h5>${_('Commit activity by day / author')}</h5>
 
    </div>
 
    
 
    <div class="table">
 
        <div id="commit_history" style="width:560px;height:300px;float:left"></div>
 
        <div style="clear: both;height: 10px"></div>
 
        <div id="overview" style="width:560px;height:100px;float:left"></div>
 
        
 
    	<div id="legend_data" style="clear:both;margin-top:10px;">
 
	    	<div id="legend_container"></div>
 
	    	<div id="legend_choices">
 
				<table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
 
	    	</div>
 
    	</div>
 
		<script type="text/javascript">
 
		/**
 
		 * Plots summary graph
 
		 *
 
		 * @class SummaryPlot
 
		 * @param {from} initial from for detailed graph
 
		 * @param {to} initial to for detailed graph
 
		 * @param {dataset}
 
		 * @param {overview_dataset}
 
		 */
 
		function SummaryPlot(from,to,dataset,overview_dataset) {
 
			var initial_ranges = {
 
			    "xaxis":{
 
				    "from":from,
 
				   	"to":to,
 
				},
 
			};
 
		    var dataset = dataset;
 
		    var overview_dataset = [overview_dataset];
 
		    var choiceContainer = YAHOO.util.Dom.get("legend_choices");
 
		    var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
 
		    var plotContainer = YAHOO.util.Dom.get('commit_history');
 
		    var overviewContainer = YAHOO.util.Dom.get('overview');
 
		    
 
		    var plot_options = {
 
				bars: {show:true,align:'center',lineWidth:4},
 
				legend: {show:true, container:"legend_container"},
 
				points: {show:true,radius:0,fill:false},
 
				yaxis: {tickDecimals:0,},
 
				xaxis: {
 
					mode: "time", 
 
					timeformat: "%d/%m",
 
				    min:from,
 
				    max:to,	
 
				}, 
 
				grid: {
 
					hoverable: true, 
 
				    clickable: true,
 
				    autoHighlight:true,
 
				    color: "#999"
 
				},
 
				//selection: {mode: "x"}
 
		    };
 
		    var overview_options = {
 
				legend:{show:false},
 
			    bars: {show:true,barWidth: 2,},
 
			    shadowSize: 0,
 
			    xaxis: {mode: "time", timeformat: "%d/%m/%y",},
 
			    yaxis: {ticks: 3, min: 0,},
 
			    grid: {color: "#999",},
 
			    selection: {mode: "x"}
 
			};
 

	
 
			/**
 
			*get dummy data needed in few places
 
			*/
 
		    function getDummyData(label){
 
		    	return {"label":label,
 
               	 "data":[{"time":0,
 
               		 "commits":0,
 
	                     "added":0,
 
	                     "changed":0,
 
	                     "removed":0,
 
                    }],
 
                    "schema":["commits"],
 
                    "color":'#ffffff',
 
           		}
 
			}
 
			
 
		    /**
 
		     * generate checkboxes accordindly to data
 
		     * @param keys
 
		     * @returns
 
		     */
 
		    function generateCheckboxes(data) {
 
			    //append checkboxes
 
			    var i = 0;
 
			    choiceContainerTable.innerHTML = '';
 
			    for(var pos in data) {
 
			    	
 
			    	data[pos].color = i;
 
			        i++;
 
			        if(data[pos].label != ''){
 
				        choiceContainerTable.innerHTML += '<tr><td>'+
 
				        '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
 
				        +data[pos].label+
 
				        '</td></tr>';
 
			        }
 
			    }	
 
		    }
 
		    
 
		    /**
 
		     * ToolTip show
 
		     */
 
		    function showTooltip(x, y, contents) {
 
		        var div=document.getElementById('tooltip');
 
		        if(!div) {
 
		            div = document.createElement('div');
 
		            div.id="tooltip";
 
		            div.style.position="absolute";
 
		            div.style.border='1px solid #fdd';
 
		            div.style.padding='2px';
 
		            div.style.backgroundColor='#fee';
 
		            document.body.appendChild(div);
 
		        }
 
		        YAHOO.util.Dom.setStyle(div, 'opacity', 0);
 
		        div.innerHTML = contents;
 
		        div.style.top=(y + 5) + "px";
 
		        div.style.left=(x + 5) + "px";
 

	
 
		        var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
 
		        anim.animate();
 
		    }
 
		    
 
			/**
 
			 * This function will detect if selected period has some changesets for this user
 
			if it does this data is then pushed for displaying
 
			Additionally it will only display users that are selected by the checkbox
 
			*/
 
		    function getDataAccordingToRanges(ranges) {
 
		    	
 
		        var data = [];
 
		        var keys = [];
 
				for(var key in dataset){
 
					var push = false;
 
					//method1 slow !!
 
		            ///*
 
		            for(var ds in dataset[key].data){
 
			            commit_data = dataset[key].data[ds];
 
			            //console.log(key);
 
			            //console.log(new Date(commit_data.time*1000));
 
			            //console.log(new Date(ranges.xaxis.from*1000));
 
			            //console.log(new Date(ranges.xaxis.to*1000));
 
			            if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
 
			            	push = true;
 
			            	break;
 
					    }
 
@@ -349,215 +349,221 @@ E.onDOMReady(function(e){
 
				if(data.length >= 1){
 
					return data;
 
				} 
 
				else{
 
					//just return dummy data for graph to plot itself
 
					return [getDummyData('')];	
 
				}
 
				
 
		    }
 
		    
 
			/**
 
			* redraw using new checkbox data
 
			*/
 
		    function plotchoiced(e,args){
 
			    var cur_data = args[0];
 
			    var cur_ranges = args[1];
 
		    	
 
				var new_data = [];
 
		    	var inputs = choiceContainer.getElementsByTagName("input");
 

	
 
		    	//show only checked labels
 
		        for(var i=0; i<inputs.length; i++) {
 
		            var checkbox_key = inputs[i].name;
 
		            
 
	                if(inputs[i].checked){
 
						for(var d in cur_data){
 
							if(cur_data[d].label == checkbox_key){
 
								new_data.push(cur_data[d]);
 
							}
 
						}			                
 
	    	        }
 
	                else{
 
		                //push dummy data to not hide the label
 
						new_data.push(getDummyData(checkbox_key));
 
			        }
 
		        }
 
						        
 
		    	var new_options = YAHOO.lang.merge(plot_options, {
 
		            xaxis: { 
 
		  	      		min: cur_ranges.xaxis.from, 
 
		  	      		max: cur_ranges.xaxis.to,
 
		  	      		mode:"time",
 
		  	      		timeformat: "%d/%m",
 
		        	}
 
		    	});
 
		    	if (!new_data){
 
					new_data = [[0,1]];
 
				}
 
		    	// do the zooming
 
		       plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
 
		       
 
		       plot.subscribe("plotselected", plotselected);
 
	
 
		       //resubscribe plothover
 
		       plot.subscribe("plothover", plothover);
 
		        
 
		       // don't fire event on the overview to prevent eternal loop
 
		       overview.setSelection(cur_ranges, true);
 
	
 
		    }
 
		    
 
			/**
 
		     * plot only selected items from overview
 
		     * @param ranges
 
		     * @returns
 
		     */
 
		    function plotselected(ranges,cur_data) {
 
			    //updates the data for new plot
 
	    		data = getDataAccordingToRanges(ranges);
 
	    		generateCheckboxes(data);
 
	    		
 
		    	var new_options = YAHOO.lang.merge(plot_options, {
 
		            xaxis: { 
 
		  	      		min: ranges.xaxis.from, 
 
		  	      		max: ranges.xaxis.to,
 
		  	      		mode:"time",
 
		  	      		timeformat: "%d/%m",
 
		        	}
 
		    	});
 
		    	// do the zooming
 
		        plot = YAHOO.widget.Flot(plotContainer, data, new_options);
 

	
 
		        plot.subscribe("plotselected", plotselected);
 

	
 
		        //resubscribe plothover
 
		        plot.subscribe("plothover", plothover);
 
		        
 
		        // don't fire event on the overview to prevent eternal loop
 
		        overview.setSelection(ranges, true);
 

	
 
		        //resubscribe choiced
 
		        YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
 
		    }
 
		    
 
		    var previousPoint = null;
 

	
 
			function plothover(o) {
 
		        var pos = o.pos;
 
		        var item = o.item;
 
		        
 
		        //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
 
		        //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
 
		        if (item) {
 
		            if (previousPoint != item.datapoint) {
 
		                previousPoint = item.datapoint;
 
		                
 
		                var tooltip = YAHOO.util.Dom.get("tooltip");
 
		                if(tooltip) {
 
		                	  tooltip.parentNode.removeChild(tooltip);
 
		                }
 
		                var x = item.datapoint.x.toFixed(2);
 
		                var y = item.datapoint.y.toFixed(2);
 
						
 
		                if (!item.series.label){
 
		                    item.series.label = 'commits';
 
		                }
 
		                var d = new Date(x*1000);
 
		                var fd = d.toDateString()
 
		                var nr_commits = parseInt(y);
 
		                
 
		                var cur_data = dataset[item.series.label].data[item.dataIndex];
 
		                var added = cur_data.added;
 
		                var changed = cur_data.changed;
 
		                var removed = cur_data.removed;
 
		                
 
		                var nr_commits_suffix = " ${_('commits')} ";
 
		                var added_suffix = " ${_('files added')} ";
 
		                var changed_suffix = " ${_('files changed')} ";
 
		                var removed_suffix = " ${_('files removed')} ";
 

	
 
		                
 
		                if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
 
						if(added==1){added_suffix=" ${_('file added')} ";}
 
						if(changed==1){changed_suffix=" ${_('file changed')} ";}
 
						if(removed==1){removed_suffix=" ${_('file removed')} ";}
 
										                
 
		                showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
 
								 +'<br/>'+
 
		                         nr_commits + nr_commits_suffix+'<br/>'+
 
		                         added + added_suffix +'<br/>'+
 
		                         changed + changed_suffix + '<br/>'+
 
		                         removed + removed_suffix + '<br/>');
 
		            }
 
		        }
 
		        else {
 
		        	  var tooltip = YAHOO.util.Dom.get("tooltip");
 
		        	  
 
			          if(tooltip) {
 
			                tooltip.parentNode.removeChild(tooltip);
 
			          }
 
		            previousPoint = null;
 
		        }
 
		    }
 
			
 
		    /**
 
		     * MAIN EXECUTION
 
		     */
 
			
 
			var data = getDataAccordingToRanges(initial_ranges);
 
			generateCheckboxes(data);
 
			
 
		    //main plot
 
		    var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
 
		    
 
			//overview
 
			var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options);
 
			
 
			//show initial selection on overview
 
			overview.setSelection(initial_ranges);    
 
			
 
		    plot.subscribe("plotselected", plotselected);
 
		    
 
		    overview.subscribe("plotselected", function (ranges) {
 
		        plot.setSelection(ranges);
 
		    });		
 
				
 
		    plot.subscribe("plothover", plothover);
 

	
 
		    YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
 
		}
 
			SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});		
 
		</script>
 

	
 
    </div>
 
</div>    
 

	
 
<div class="box">    
 
    <div class="title">
 
        <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
 
    </div>    
 
    <div class="table">
 
        <%include file='../shortlog/shortlog_data.html'/>
 
        %if c.repo_changesets:
 
        ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
 
        %endif
 
    </div>
 
</div>
 
<div class="box">    
 
    <div class="title">
 
        <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
 
    </div>    
 
    <div class="table">
 
        <%include file='../tags/tags_data.html'/>
 
        %if c.repo_changesets:
 
        ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
 
        %endif
 
    </div>
 
</div>
 
<div class="box">
 
    <div class="title">
 
        <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
 
    </div>    
 
    <div class="table">
 
        <%include file='../branches/branches_data.html'/>
 
        %if c.repo_changesets:
 
        ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
 
        %endif
 
    </div>      
 
</div> 
 

	
 
</%def>    
 
\ No newline at end of file
0 comments (0 inline, 0 general)