Changeset - 2f89beda06a1
[Not reviewed]
beta
0 4 0
Marcin Kuzminski - 15 years ago 2010-11-23 23:49:12
marcin@python-works.com
Added icons with numbers of followers and number of forks
4 files changed with 54 insertions and 17 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/base.py
Show inline comments
 
"""The base Controller API
 

	
 
Provides the BaseController class for subclassing.
 
"""
 
from pylons import config, tmpl_context as c, request, session
 
from pylons.controllers import WSGIController
 
from pylons.templating import render_mako as render
 
from rhodecode import __version__
 
from rhodecode.lib import auth
 
from rhodecode.lib.utils import get_repo_slug
 
from rhodecode.model import meta
 
from rhodecode.model.scm import ScmModel
 
from rhodecode import BACKENDS
 

	
 
class BaseController(WSGIController):
 

	
 
    def __before__(self):
 
        c.rhodecode_version = __version__
 
        c.rhodecode_name = config['rhodecode_title']
 
        c.repo_name = get_repo_slug(request)
 
        c.cached_repo_list = ScmModel().get_repos()
 
        c.backends = BACKENDS.keys()
 

	
 
        if c.repo_name:
 
            cached_repo = ScmModel().get(c.repo_name)
 
            scm_model = ScmModel()
 
            cached_repo = scm_model.get(c.repo_name)
 

	
 
            if cached_repo:
 
                c.repository_tags = cached_repo.tags
 
                c.repository_branches = cached_repo.branches
 
                c.repository_followers = scm_model.get_followers(cached_repo.dbrepo.repo_id)
 
                c.repository_forks = scm_model.get_forks(cached_repo.dbrepo.repo_id)
 
            else:
 
                c.repository_tags = {}
 
                c.repository_branches = {}
 
                c.repository_followers = 0
 
                c.repository_forks = 0
 

	
 
        self.sa = meta.Session()
 

	
 
    def __call__(self, environ, start_response):
 
        """Invoke the Controller"""
 
        # WSGIController.__call__ dispatches to the Controller method
 
        # the request is routed to. This routing information is
 
        # available in environ['pylons.routes_dict']
 
        try:
 
            #putting this here makes sure that we update permissions every time
 
            self.rhodecode_user = c.rhodecode_user = auth.get_user(session)
 
            return WSGIController.__call__(self, environ, start_response)
 
        finally:
 
            meta.Session.remove()
rhodecode/model/scm.py
Show inline comments
 
@@ -31,50 +31,50 @@ from rhodecode.lib.utils import get_repo
 
from rhodecode.model import meta
 
from rhodecode.model.db import Repository, User, RhodeCodeUi, CacheInvalidation, \
 
    UserFollowing
 
from rhodecode.model.caching_query import FromCache
 
from sqlalchemy.orm import joinedload
 
from sqlalchemy.orm.session import make_transient
 
from vcs import get_backend
 
from vcs.utils.helpers import get_scm
 
from vcs.exceptions import RepositoryError, VCSError
 
from vcs.utils.lazy import LazyProperty
 
import traceback
 
import logging
 
import os
 
import time
 

	
 
log = logging.getLogger(__name__)
 

	
 
class UserTemp(object):
 
    def __init__(self, user_id):
 
        self.user_id = user_id
 

	
 
class RepoTemp(object):
 
    def __init__(self, repo_id):
 
        self.repo_id = repo_id
 
        
 
           
 

	
 

	
 
class ScmModel(object):
 
    """
 
    Mercurial Model
 
    """
 

	
 
    def __init__(self):
 
        self.sa = meta.Session()
 

	
 
    @LazyProperty
 
    def repos_path(self):
 
        """
 
        Get's the repositories root path from database
 
        """
 
        q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
 

	
 
        return q.ui_value
 

	
 
    def repo_scan(self, repos_path, baseui, initial=False):
 
        """
 
        Listing of repositories in given path. This path should not be a 
 
        repository itself. Return a dictionary of repository objects
 
        
 
        :param repos_path: path to directory containing repositories
 
        :param baseui
 
@@ -215,71 +215,71 @@ class ScmModel(object):
 
            .filter(CacheInvalidation.cache_key == repo_name).scalar()
 

	
 
        if cache:
 
            #mark this cache as inactive
 
            cache.cache_active = False
 
        else:
 
            log.debug('cache key not found in invalidation db -> creating one')
 
            cache = CacheInvalidation(repo_name)
 

	
 
        try:
 
            self.sa.add(cache)
 
            self.sa.commit()
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 

	
 

	
 
    def toggle_following_repo(self, follow_repo_id, user_id):
 

	
 
        f = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.follows_repo_id == follow_repo_id)\
 
            .filter(UserFollowing.user_id == user_id).scalar()
 

	
 
        if f is not None:
 
                    
 

	
 
            try:
 
                self.sa.delete(f)
 
                self.sa.commit()
 
                action_logger(UserTemp(user_id),
 
                              'stopped_following_repo',
 
                              RepoTemp(follow_repo_id))                
 
                              RepoTemp(follow_repo_id))
 
                return
 
            except:
 
                log.error(traceback.format_exc())
 
                self.sa.rollback()
 
                raise
 

	
 

	
 
        try:
 
            f = UserFollowing()
 
            f.user_id = user_id
 
            f.follows_repo_id = follow_repo_id
 
            self.sa.add(f)
 
            self.sa.commit()
 
            action_logger(UserTemp(user_id),
 
                          'started_following_repo',
 
                          RepoTemp(follow_repo_id))             
 
                          RepoTemp(follow_repo_id))
 
        except:
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def toggle_following_user(self, follow_user_id , user_id):
 
        f = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.follows_user_id == follow_user_id)\
 
            .filter(UserFollowing.user_id == user_id).scalar()
 

	
 
        if f is not None:
 
            try:
 
                self.sa.delete(f)
 
                self.sa.commit()
 
                return
 
            except:
 
                log.error(traceback.format_exc())
 
                self.sa.rollback()
 
                raise
 

	
 
        try:
 
            f = UserFollowing()
 
            f.user_id = user_id
 
            f.follows_user_id = follow_user_id
 
@@ -289,48 +289,55 @@ class ScmModel(object):
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 
    def is_following_repo(self, repo_name, user_id):
 
        r = self.sa.query(Repository)\
 
            .filter(Repository.repo_name == repo_name).scalar()
 

	
 
        f = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.follows_repository == r)\
 
            .filter(UserFollowing.user_id == user_id).scalar()
 

	
 
        return f is not None
 

	
 
    def is_following_user(self, username, user_id):
 
        u = self.sa.query(User)\
 
            .filter(User.username == username).scalar()
 

	
 
        f = self.sa.query(UserFollowing)\
 
            .filter(UserFollowing.follows_user == u)\
 
            .filter(UserFollowing.user_id == user_id).scalar()
 

	
 
        return f is not None
 

	
 
    def get_followers(self, repo_id):
 
        return self.sa.query(UserFollowing)\
 
                .filter(UserFollowing.follows_repo_id == repo_id).count()
 

	
 
    def get_forks(self, repo_id):
 
        return self.sa.query(Repository)\
 
                .filter(Repository.fork_id == repo_id).count()
 

	
 
    def _should_invalidate(self, repo_name):
 
        """
 
        Looks up database for invalidation signals for this repo_name
 
        :param repo_name:
 
        """
 

	
 
        ret = self.sa.query(CacheInvalidation)\
 
            .options(FromCache('sql_cache_short',
 
                           'get_invalidation_%s' % repo_name))\
 
            .filter(CacheInvalidation.cache_key == repo_name)\
 
            .filter(CacheInvalidation.cache_active == False)\
 
            .scalar()
 

	
 
        return ret
 

	
 
    def _mark_invalidated(self, cache_key):
 
        """
 
        Marks all occurences of cache to invaldation as already invalidated
 
        @param repo_name:
 
        """
 
        if cache_key:
 
            log.debug('marking %s as already invalidated', cache_key)
 
        try:
rhodecode/public/css/style.css
Show inline comments
 
@@ -281,89 +281,103 @@ margin:10px 5px 0 0;
 
padding:0;
 
}
 
 
#header #header-inner #quick li {
 
position:relative;
 
float:left;
 
margin:0 5px 0 0;
 
padding:0;
 
}
 
 
#header #header-inner #quick li a {
 
top:0;
 
left:0;
 
height:1%;
 
display:block;
 
clear:both;
 
overflow:hidden;
 
color:#FFF;
 
font-weight:700;
 
text-decoration:none;
 
background:#369 url("../../images/quick_l.png") no-repeat top left;
 
padding:0;
 
}
 
 
#header #header-inner #quick li span.short {
 
padding:9px 6px 8px 6px;
 
}
 
 
#header #header-inner #quick li span {
 
top:0;
 
right:0;
 
height:1%;
 
display:block;
 
float:left;
 
background:url("../../images/quick_r.png") no-repeat top right;
 
border-left:1px solid #3f6f9f;
 
margin:0;
 
padding:10px 12px 8px 10px;
 
}
 
 
#header #header-inner #quick li span.normal {
 
border:none;
 
padding:10px 12px 8px;
 
}
 
 
#header #header-inner #quick li span.icon {
 
top:0;
 
left:0;
 
border-left:none;
 
background:url("../../images/quick_l.png") no-repeat top left;
 
border-right:1px solid #2e5c89;
 
padding:8px 8px 4px;
 
}
 
 
#header #header-inner #quick li span.icon_short {
 
top:0;
 
left:0;
 
border-left:none;
 
background:url("../../images/quick_l.png") no-repeat top left;
 
border-right:1px solid #2e5c89;
 
padding:9px 4px 4px;
 
}
 
 
#header #header-inner #quick li a:hover {
 
background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
 
}
 
 
#header #header-inner #quick li a:hover span {
 
border-left:1px solid #545454;
 
background:url("../../images/quick_r_selected.png") no-repeat top right;
 
}
 
 
#header #header-inner #quick li a:hover span.icon {
 
#header #header-inner #quick li a:hover span.icon,#header #header-inner #quick li a:hover span.icon_short {
 
border-left:none;
 
border-right:1px solid #464646;
 
background:url("../../images/quick_l_selected.png") no-repeat top left;
 
}
 
 
 
#header #header-inner #quick ul {
 
top:29px;
 
right:0;
 
min-width:200px;
 
display:none;
 
position:absolute;
 
background:#FFF;
 
border:1px solid #666;
 
border-top:1px solid #003367;
 
z-index:100;
 
margin:0;
 
padding:0;
 
}
 
 
#header #header-inner #quick ul.repo_switcher {
 
max-height:275px;
 
overflow-x:hidden;
 
overflow-y:auto;
 
}
 
 
#header #header-inner #quick .repo_switcher_type{
 
position:absolute;
 
left:0;
 
top:9px; 
rhodecode/templates/base/base.html
Show inline comments
 
@@ -191,61 +191,72 @@
 
                   <a title="${_('Options')}" href="#">
 
                   <span class="icon">
 
                       <img src="/images/icons/table_gear.png" alt="${_('Admin')}" />
 
                   </span>
 
                   <span>${_('Options')}</span>                 
 
                   </a>
 
                   <ul>
 
                   %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
 
                   	<li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
 
                   %endif	
 
                   	<li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
 
                   	<li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
 
                    
 
                    %if h.HasPermissionAll('hg.admin')('access admin main page'):
 
                    <li>
 
                       ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}  
 
                        <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                    
 
                    %endif
 

	
 
                
 
##                   %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
 
##                   	<li class="last">
 
##                   	${h.link_to(_('delete'),'#',class_='delete')}
 
##	                  ${h.form(url('repo_settings_delete', repo_name=c.repo_name),method='delete')}
 
##	                    ${h.submit('remove_%s' % c.repo_name,'delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
 
##	                  ${h.end_form()}
 
##                   	</li>
 
##                   	%endif
 
                   </ul>             
 
                </li>
 
                
 
                <li>
 
                    <a title="${_('Followers')}" href="#">
 
                    <span class="icon_short">
 
                        <img src="/images/icons/heart.png" alt="${_('Followers')}" />
 
                    </span>
 
                    <span class="short">${c.repository_followers}</span>
 
                    </a>
 
                </li>
 
                <li>
 
                    <a title="${_('Forks')}" href="#">
 
                    <span class="icon_short">
 
                        <img src="/images/icons/arrow_divide.png" alt="${_('Forks')}" />
 
                    </span>
 
                    <span class="short">${c.repository_forks}</span>
 
                    </a>
 
                </li>                
 
                
 
                
 
                
 
	        </ul>
 
		%else:
 
		    ##ROOT MENU
 
            <ul id="quick">
 
                <li>
 
                    <a title="${_('Home')}"  href="${h.url('home')}">
 
                    <span class="icon">
 
                        <img src="/images/icons/home_16.png" alt="${_('Home')}" />
 
                    </span>
 
                    <span>${_('Home')}</span>                 
 
                    </a>        
 
                </li>
 
                
 
                <li>
 
                    <a title="${_('Journal')}"  href="${h.url('journal')}">
 
                    <span class="icon">
 
                        <img src="/images/icons/book.png" alt="${_('Journal')}" />
 
                    </span>
 
                    <span>${_('Journal')}</span>                 
 
                    </a>        
 
                </li>
 
                                
 
                <li>
 
                    <a title="${_('Search')}"  href="${h.url('search')}">
0 comments (0 inline, 0 general)