Changeset - 405b80e4ccd5
[Not reviewed]
beta
0 7 0
Marcin Kuzminski - 15 years ago 2011-02-12 21:21:23
marcin@python-works.com
Major refactoring, removed when possible calls to app globals.
Refactored models to fetch the paths needed for scans from database directly
small fixes in base
7 files changed with 47 insertions and 55 deletions:
0 comments (0 inline, 0 general)
rhodecode/config/environment.py
Show inline comments
 
@@ -4,25 +4,25 @@ import os
 
import logging
 

	
 
from mako.lookup import TemplateLookup
 
from pylons.configuration import PylonsConfig
 
from pylons.error import handle_mako_error
 
from sqlalchemy import engine_from_config
 

	
 
import rhodecode.lib.app_globals as app_globals
 
import rhodecode.lib.helpers
 

	
 
from rhodecode.config.routing import make_map
 
from rhodecode.lib import celerypylons
 
from rhodecode.lib.auth import set_available_permissions, set_base_path
 
from rhodecode.lib.auth import set_available_permissions
 
from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
 
from rhodecode.model import init_model
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.lib.timerproxy import TimerProxy
 

	
 
log = logging.getLogger(__name__)
 

	
 
def load_environment(global_conf, app_conf, initial=False):
 
    """Configure the Pylons environment via the ``pylons.config``
 
    object
 
    """
 
    config = PylonsConfig()
 
@@ -63,24 +63,22 @@ def load_environment(global_conf, app_co
 
        create_test_index(TESTS_TMP_PATH, True)
 

	
 
    #MULTIPLE DB configs
 
    # Setup the SQLAlchemy database engine
 
    if config['debug'] and not test:
 
        #use query time debugging.
 
        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
 
                                                            proxy=TimerProxy())
 
    else:
 
        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 
    init_model(sa_engine_db1)
 
    #init baseui
 
    config['pylons.app_globals'].baseui = make_ui('db')
 

	
 
    g = config['pylons.app_globals']
 
    repo2db_mapper(ScmModel().repo_scan(g.paths[0][1], g.baseui))
 
    repos_path = make_ui('db').configitems('paths')[0][1]
 
    repo2db_mapper(ScmModel().repo_scan(repos_path))
 
    set_available_permissions(config)
 
    set_base_path(config)
 
    config['base_path'] = repos_path
 
    set_rhodecode_config(config)
 
    # CONFIGURATION OPTIONS HERE (note: all config options will override
 
    # any Pylons config options)
 

	
 
    return config
rhodecode/controllers/admin/settings.py
Show inline comments
 
@@ -22,43 +22,42 @@
 
# 
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 

	
 
import logging
 
import traceback
 
import formencode
 

	
 
from sqlalchemy import func
 
from formencode import htmlfill
 
from pylons import request, session, tmpl_context as c, url, app_globals as g, \
 
    config
 
from pylons import request, session, tmpl_context as c, url, config
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
 
    HasPermissionAnyDecorator, NotAnonymous
 
from rhodecode.lib.base import BaseController, render
 
from rhodecode.lib.celerylib import tasks, run_task
 
from rhodecode.lib.utils import repo2db_mapper, invalidate_cache, \
 
    set_rhodecode_config, repo_name_slug
 
from rhodecode.model.db import RhodeCodeUi, Repository
 
from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
 
    ApplicationUiSettingsForm
 
from rhodecode.model.scm import ScmModel
 
from rhodecode.model.settings import SettingsModel
 
from rhodecode.model.user import UserModel
 

	
 
from rhodecode.model.repo import RepoModel
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class SettingsController(BaseController):
 
    """REST Controller styled on the Atom Publishing Protocol"""
 
    # To properly map this controller, ensure your config/routing.py
 
    # file has a resource setup:
 
    #     map.resource('setting', 'settings', controller='admin/settings', 
 
    #         path_prefix='/admin', name_prefix='admin_')
 

	
 

	
 
@@ -96,26 +95,25 @@ class SettingsController(BaseController)
 
    @HasPermissionAllDecorator('hg.admin')
 
    def update(self, setting_id):
 
        """PUT /admin/settings/setting_id: Update an existing item"""
 
        # Forms posted to this method should contain a hidden field:
 
        #    <input type="hidden" name="_method" value="PUT" />
 
        # Or using helpers:
 
        #    h.form(url('admin_setting', setting_id=ID),
 
        #           method='put')
 
        # url('admin_setting', setting_id=ID)
 
        if setting_id == 'mapping':
 
            rm_obsolete = request.POST.get('destroy', False)
 
            log.debug('Rescanning directories with destroy=%s', rm_obsolete)
 

	
 
            initial = ScmModel().repo_scan(g.paths[0][1], g.baseui)
 
            initial = ScmModel().repo_scan()
 
            for repo_name in initial.keys():
 
                invalidate_cache('get_repo_cached_%s' % repo_name)
 

	
 
            repo2db_mapper(initial, rm_obsolete)
 

	
 
            h.flash(_('Repositories successfully rescanned'), category='success')
 

	
 
        if setting_id == 'whoosh':
 
            repo_location = self.get_hg_ui_settings()['paths_root_path']
 
            full_index = request.POST.get('full_index', False)
 
            task = run_task(tasks.whoosh_index, repo_location, full_index)
 

	
rhodecode/lib/app_globals.py
Show inline comments
 
"""The application's Globals object"""
 

	
 
from beaker.cache import CacheManager
 
from beaker.util import parse_cache_config_options
 
from vcs.utils.lazy import LazyProperty
 

	
 
class Globals(object):
 
    """Globals acts as a container for objects available throughout the
 
    life of the application
 

	
 
    """
 

	
 
    def __init__(self, config):
 
        """One instance of Globals is created during application
 
        initialization and is available during requests via the
 
        'app_globals' variable
 

	
 
        """
 
        self.cache = CacheManager(**parse_cache_config_options(config))
 
        self.available_permissions = None   # propagated after init_model
 
        self.baseui = None                  # propagated after init_model        
 

	
 
    @LazyProperty
 
    def paths(self):
 
        if self.baseui:
 
            return self.baseui.configitems('paths')
 

	
 
    @LazyProperty
 
    def base_path(self):
 
        if self.baseui:
 
            return self.paths[0][1]
rhodecode/lib/auth.py
Show inline comments
 
@@ -204,28 +204,24 @@ def set_available_permissions(config):
 
    """
 
    log.info('getting information about all available permissions')
 
    try:
 
        sa = meta.Session()
 
        all_perms = sa.query(Permission).all()
 
    except:
 
        pass
 
    finally:
 
        meta.Session.remove()
 

	
 
    config['available_permissions'] = [x.permission_name for x in all_perms]
 

	
 
def set_base_path(config):
 
    config['base_path'] = config['pylons.app_globals'].base_path
 

	
 

	
 
def fill_perms(user):
 
    """Fills user permission attribute with permissions taken from database
 
    works for permissions given for repositories, and for permissions that
 
    as part of beeing group member
 
    
 
    :param user: user instance to fill his perms
 
    """
 

	
 
    sa = meta.Session()
 
    user.permissions['repositories'] = {}
 
    user.permissions['global'] = set()
 

	
rhodecode/lib/base.py
Show inline comments
 
@@ -10,29 +10,30 @@ 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.get('rhodecode_title')
 
        c.ga_code = config.get('rhodecode_ga_code')
 
        c.repo_name = get_repo_slug(request)
 
        c.cached_repo_list = ScmModel().get_repos()
 
        c.backends = BACKENDS.keys()
 
        self.cut_off_limit = int(config.get('cut_off_limit'))
 

	
 
        self.sa = meta.Session()
 
        scm_model = ScmModel(self.sa)
 
        c.cached_repo_list = scm_model.get_repos()
 
        #c.unread_journal = scm_model.get_unread_journal()
 

	
 
        if c.repo_name:
 
            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 = {}
rhodecode/lib/indexers/daemon.py
Show inline comments
 
@@ -72,25 +72,25 @@ class WhooshIndexingDaemon(object):
 
    def __init__(self, indexname='HG_INDEX', index_location=None,
 
                 repo_location=None, sa=None, repo_list=None):
 
        self.indexname = indexname
 

	
 
        self.index_location = index_location
 
        if not index_location:
 
            raise Exception('You have to provide index location')
 

	
 
        self.repo_location = repo_location
 
        if not repo_location:
 
            raise Exception('You have to provide repositories location')
 

	
 
        self.repo_paths = ScmModel(sa).repo_scan(self.repo_location, None)
 
        self.repo_paths = ScmModel(sa).repo_scan(self.repo_location)
 

	
 
        if repo_list:
 
            filtered_repo_paths = {}
 
            for repo_name, repo in self.repo_paths.items():
 
                if repo_name in repo_list:
 
                    filtered_repo_paths[repo.name] = repo
 

	
 
            self.repo_paths = filtered_repo_paths
 

	
 

	
 
        self.initial = False
 
        if not os.path.isdir(self.index_location):
rhodecode/model/repo.py
Show inline comments
 
@@ -21,76 +21,87 @@
 
# GNU General Public License for more details.
 
# 
 
# You should have received a copy of the GNU General Public License
 
# along with this program; if not, write to the Free Software
 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
# MA  02110-1301, USA.
 
import os
 
import shutil
 
import logging
 
import traceback
 
from datetime import datetime
 

	
 
from sqlalchemy.orm import joinedload
 

	
 
from vcs.utils.lazy import LazyProperty
 
from vcs.backends import get_backend
 

	
 
from rhodecode.model import BaseModel
 
from rhodecode.model.caching_query import FromCache
 
from rhodecode.model.db import Repository, RepoToPerm, User, Permission, \
 
    Statistics, UsersGroup, UsersGroupToPerm
 
    Statistics, UsersGroup, UsersGroupToPerm, RhodeCodeUi
 
from rhodecode.model.user import UserModel
 
from rhodecode.model.users_group import UsersGroupMember, UsersGroupModel
 

	
 
from vcs.backends import get_backend
 

	
 
log = logging.getLogger(__name__)
 

	
 
class RepoModel(BaseModel):
 

	
 
    def __init__(self, sa=None):
 
        try:
 
            from pylons import app_globals
 
            self._base_path = app_globals.base_path
 
        except:
 
            self._base_path = None
 

	
 
        super(RepoModel, self).__init__(sa)
 
    @LazyProperty
 
    def repos_path(self):
 
        """Get's the repositories root path from database
 
        """
 

	
 
    @property
 
    def base_path(self):
 
        if self._base_path is None:
 
            raise Exception('Base Path is empty, try set this after'
 
                            'class initialization when not having '
 
                            'app_globals available')
 
        return self._base_path
 

	
 
        super(RepoModel, self).__init__()
 

	
 
        q = self.sa.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == '/').one()
 
        return q.ui_value
 

	
 
    def get(self, repo_id, cache=False):
 
        repo = self.sa.query(Repository)\
 
            .filter(Repository.repo_id == repo_id)
 

	
 
        if cache:
 
            repo = repo.options(FromCache("sql_cache_short",
 
                                          "get_repo_%s" % repo_id))
 
        return repo.scalar()
 

	
 

	
 
    def get_by_repo_name(self, repo_name, cache=False):
 
        repo = self.sa.query(Repository)\
 
            .filter(Repository.repo_name == repo_name)
 

	
 
        if cache:
 
            repo = repo.options(FromCache("sql_cache_short",
 
                                          "get_repo_%s" % repo_name))
 
        return repo.scalar()
 

	
 

	
 
    def get_full(self, repo_name, cache=False, invalidate=False):
 
        repo = self.sa.query(Repository)\
 
            .options(joinedload(Repository.fork))\
 
            .options(joinedload(Repository.user))\
 
            .options(joinedload(Repository.followers))\
 
            .options(joinedload(Repository.repo_to_perm))\
 
            .options(joinedload(Repository.users_group_to_perm))\
 
            .filter(Repository.repo_name == repo_name)\
 

	
 
        if cache:
 
            repo = repo.options(FromCache("sql_cache_long",
 
                                          "get_repo_full_%s" % repo_name))
 
        if invalidate:
 
            repo.invalidate()
 

	
 
        return repo.scalar()
 

	
 

	
 
    def get_users_js(self):
 

	
 
        users = self.sa.query(User).filter(User.active == True).all()
 
        u_tmpl = '''{id:%s, fname:"%s", lname:"%s", nname:"%s"},'''
 
        users_array = '[%s]' % '\n'.join([u_tmpl % (u.user_id, u.name,
 
                                                    u.lastname, u.username)
 
                                        for u in users])
 
        return users_array
 

	
 

	
 
    def get_users_groups_js(self):
 
        users_groups = self.sa.query(UsersGroup)\
 
@@ -281,51 +292,51 @@ class RepoModel(BaseModel):
 
            log.error(traceback.format_exc())
 
            self.sa.rollback()
 
            raise
 

	
 

	
 
    def __create_repo(self, repo_name, alias):
 
        """
 
        makes repository on filesystem
 
        :param repo_name:
 
        :param alias:
 
        """
 
        from rhodecode.lib.utils import check_repo
 
        repo_path = os.path.join(self.base_path, repo_name)
 
        if check_repo(repo_name, self.base_path):
 
        repo_path = os.path.join(self.repos_path, repo_name)
 
        if check_repo(repo_name, self.repos_path):
 
            log.info('creating repo %s in %s', repo_name, repo_path)
 
            backend = get_backend(alias)
 
            backend(repo_path, create=True)
 

	
 
    def __rename_repo(self, old, new):
 
        """
 
        renames repository on filesystem
 
        :param old: old name
 
        :param new: new name
 
        """
 
        log.info('renaming repo from %s to %s', old, new)
 

	
 
        old_path = os.path.join(self.base_path, old)
 
        new_path = os.path.join(self.base_path, new)
 
        old_path = os.path.join(self.repos_path, old)
 
        new_path = os.path.join(self.repos_path, new)
 
        if os.path.isdir(new_path):
 
            raise Exception('Was trying to rename to already existing dir %s',
 
                            new_path)
 
        shutil.move(old_path, new_path)
 

	
 
    def __delete_repo(self, repo):
 
        """
 
        removes repo from filesystem, the removal is acctually made by
 
        added rm__ prefix into dir, and rename internat .hg/.git dirs so this
 
        repository is no longer valid for rhodecode, can be undeleted later on
 
        by reverting the renames on this repository
 
        :param repo: repo object
 
        """
 
        rm_path = os.path.join(self.base_path, repo.repo_name)
 
        rm_path = os.path.join(self.repos_path, repo.repo_name)
 
        log.info("Removing %s", rm_path)
 
        #disable hg/git
 
        alias = repo.repo_type
 
        shutil.move(os.path.join(rm_path, '.%s' % alias),
 
                    os.path.join(rm_path, 'rm__.%s' % alias))
 
        #disable repo
 
        shutil.move(rm_path, os.path.join(self.base_path, 'rm__%s__%s' \
 
        shutil.move(rm_path, os.path.join(self.repos_path, 'rm__%s__%s' \
 
                                          % (datetime.today().isoformat(),
 
                                             repo.repo_name)))
0 comments (0 inline, 0 general)