Changeset - 1ef52a70f3b7
[Not reviewed]
default
1 9 0
Marcin Kuzminski - 15 years ago 2010-07-14 02:28:32
marcin@python-works.com
Made config file free configuration based on database and capable of beeing manage via application settings + some code cleanups
10 files changed with 132 insertions and 89 deletions:
0 comments (0 inline, 0 general)
pylons_app/config/environment.py
Show inline comments
 
@@ -4,7 +4,7 @@ from pylons.configuration import PylonsC
 
from pylons.error import handle_mako_error
 
from pylons_app.config.routing import make_map
 
from pylons_app.lib.auth import set_available_permissions, set_base_path
 
from pylons_app.lib.utils import repo2db_mapper
 
from pylons_app.lib.utils import repo2db_mapper, make_ui, set_hg_app_config
 
from pylons_app.model import init_model
 
from pylons_app.model.hg_model import _get_repos_cached_initial
 
from sqlalchemy import engine_from_config
 
@@ -61,9 +61,12 @@ def load_environment(global_conf, app_co
 
        sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
 

	
 
    init_model(sa_engine_db1)
 
    config['pylons.app_globals'].baseui = make_ui('db')
 
    
 
    repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals']))
 
    set_available_permissions(config)
 
    set_base_path(config)
 
    set_hg_app_config(config)
 
    # CONFIGURATION OPTIONS HERE (note: all config options will override
 
    # any Pylons config options)
 
    
pylons_app/config/middleware.py
Show inline comments
 
@@ -41,7 +41,6 @@ def make_app(global_conf, full_stack=Tru
 
    app = SessionMiddleware(app, config)
 
    
 
    # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
 
    #set the https based on HTTP_X_URL_SCHEME
 
    
 
    app = SimpleHg(app, config)
 
    
pylons_app/config/repositories.config_tmpl
Show inline comments
 
deleted file
pylons_app/controllers/settings.py
Show inline comments
 
@@ -70,8 +70,6 @@ class SettingsController(BaseController)
 
        )  
 

	
 
    def update(self, repo_name):
 
        print request.POST
 
        print 'x' * 110
 
        repo_model = RepoModel()
 
        _form = RepoSettingsForm(edit=True)()
 
        try:
pylons_app/lib/app_globals.py
Show inline comments
 
@@ -2,10 +2,9 @@
 

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

	
 
class Globals(object):
 

	
 
    """Globals acts as a container for objects available throughout the
 
    life of the application
 

	
 
@@ -18,8 +17,17 @@ class Globals(object):
 

	
 
        """
 
        self.cache = CacheManager(**parse_cache_config_options(config))
 
        self.baseui = make_ui(config['hg_app_repo_conf'])
 
        self.paths = self.baseui.configitems('paths')
 
        self.base_path = self.paths[0][1].replace('*', '')
 
        self.changeset_annotation_colors = {}
 
        self.available_permissions = None # propagated after init_model
 
        self.app_title = 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].replace('*', '')            
pylons_app/lib/db_manage.py
Show inline comments
 
@@ -33,7 +33,7 @@ sys.path.append(ROOT)
 

	
 
from pylons_app.lib.auth import get_crypt_password
 
from pylons_app.model import init_model
 
from pylons_app.model.db import User, Permission
 
from pylons_app.model.db import User, Permission, HgAppUi
 
from pylons_app.model.meta import Session, Base
 
from sqlalchemy.engine import create_engine
 
import logging
 
@@ -80,6 +80,61 @@ class DbManage(object):
 
        password = getpass.getpass('Specify admin password:')
 
        self.create_user(username, password, True)
 
        
 
    def config_prompt(self):
 
        log.info('Seting up repositories.config')
 
        
 
        
 
        path = raw_input('Specify valid full path to your repositories'
 
                        ' you can change this later application settings:')
 
        
 
        if not os.path.isdir(path):
 
            log.error('You entered wrong path')
 
            sys.exit()
 
        
 
        hooks = HgAppUi()
 
        hooks.ui_section = 'hooks'
 
        hooks.ui_key = 'changegroup'
 
        hooks.ui_value = 'hg update >&2'
 
        
 
        web1 = HgAppUi()
 
        web1.ui_section = 'web'
 
        web1.ui_key = 'push_ssl'
 
        web1.ui_value = 'false'
 
                
 
        web2 = HgAppUi()
 
        web2.ui_section = 'web'
 
        web2.ui_key = 'allow_archive'
 
        web2.ui_value = 'gz zip bz2'
 
                
 
        web3 = HgAppUi()
 
        web3.ui_section = 'web'
 
        web3.ui_key = 'allow_push'
 
        web3.ui_value = '*'
 
        
 
        web4 = HgAppUi()
 
        web4.ui_section = 'web'
 
        web4.ui_key = 'baseurl'
 
        web4.ui_value = '/'                        
 
        
 
        paths = HgAppUi()
 
        paths.ui_section = 'paths'
 
        paths.ui_key = '/'
 
        paths.ui_value = os.path.join(path, '*')
 
        
 
        
 
        try:
 
            self.sa.add(hooks)
 
            self.sa.add(web1)
 
            self.sa.add(web2)
 
            self.sa.add(web3)
 
            self.sa.add(web4)
 
            self.sa.add(paths)
 
            self.sa.commit()
 
        except:
 
            self.sa.rollback()
 
            raise        
 
        log.info('created ui config')
 
                    
 
    def create_user(self, username, password, admin=False):
 
        
 
        log.info('creating default user')
 
@@ -93,8 +148,6 @@ class DbManage(object):
 
        def_user.admin = False
 
        def_user.active = False
 
        
 
        self.sa.add(def_user)
 
        
 
        log.info('creating administrator user %s', username)
 
        new_user = User()
 
        new_user.username = username
 
@@ -106,6 +159,7 @@ class DbManage(object):
 
        new_user.active = True
 
        
 
        try:
 
            self.sa.add(def_user)
 
            self.sa.add(new_user)
 
            self.sa.commit()
 
        except:
pylons_app/lib/middleware/simplehg.py
Show inline comments
 
@@ -50,7 +50,7 @@ class SimpleHg(object):
 
        self.application = application
 
        self.config = config
 
        #authenticate this mercurial request using 
 
        realm = '%s %s' % (self.config['hg_app_name'], 'mercurial repository')
 
        realm = self.config['hg_app_auth_realm']
 
        self.authenticate = AuthBasicAuthenticator(realm, authfunc)
 
        
 
    def __call__(self, environ, start_response):
 
@@ -111,14 +111,13 @@ class SimpleHg(object):
 
            # MERCURIAL REQUEST HANDLING
 
            #===================================================================
 
            environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
 
            self.baseui = make_ui(self.config['hg_app_repo_conf'])
 
            self.baseui = make_ui('db')
 
            self.basepath = self.config['base_path']
 
            self.repo_path = os.path.join(self.basepath, repo_name)
 

	
 
            #quick check if that dir exists...
 
            if check_repo_fast(repo_name, self.basepath):
 
                return HTTPNotFound()(environ, start_response)
 
            
 
            try:
 
                app = wsgiapplication(self.__make_app)
 
            except RepoError as e:
 
@@ -155,7 +154,7 @@ class SimpleHg(object):
 
        return chain(org_response, custom_messages(messages))
 

	
 
    def __make_app(self):
 
        hgserve = hgweb(self.repo_path)
 
        hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
 
        return  self.__load_web_settings(hgserve)
 
    
 
    def __get_environ_user(self, environ):
 
@@ -214,10 +213,12 @@ class SimpleHg(object):
 
           
 
                   
 
    def __load_web_settings(self, hgserve):
 
        repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
 
        #set the global ui for hgserve
 
        hgserve.repo.ui = self.baseui
 
        
 
        hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
 
        repoui = make_ui('file', hgrc, False)
 
        
 
        if repoui:
 
            #set the repository based config
 
            hgserve.repo.ui = repoui
pylons_app/lib/utils.py
Show inline comments
 
@@ -27,7 +27,7 @@ import os
 
import logging
 
from mercurial import ui, config, hg
 
from mercurial.error import RepoError
 
from pylons_app.model.db import Repository, User
 
from pylons_app.model.db import Repository, User, HgAppUi
 
log = logging.getLogger(__name__)
 

	
 

	
 
@@ -75,53 +75,58 @@ def check_repo(repo_name, base_path, ver
 
        log.info('%s repo is free for creation', repo_name)
 
        return True
 

	
 
def make_ui(path=None, checkpaths=True):        
 
def make_ui(read_from='file', path=None, checkpaths=True):        
 
    """
 
    A funcion that will read python rc files and make an ui from read options
 
    A function that will read python rc files or database
 
    and make an mercurial ui object from read options
 
    
 
    @param path: path to mercurial config file
 
    @param checkpaths: check the path
 
    @param read_from: read from 'file' or 'db'
 
    """
 
    if not path:
 
        log.error('repos config path is empty !')
 
    #propagated from mercurial documentation
 
    sections = ['alias', 'auth',
 
                'decode/encode', 'defaults',
 
                'diff', 'email',
 
                'extensions', 'format',
 
                'merge-patterns', 'merge-tools',
 
                'hooks', 'http_proxy',
 
                'smtp', 'patch',
 
                'paths', 'profiling',
 
                'server', 'trusted',
 
                'ui', 'web', ]
 
    baseui = ui.ui()
 
    
 
                
 
    if read_from == 'file':
 
    if not os.path.isfile(path):
 
        log.warning('Unable to read config file %s' % path)
 
        return False
 
    #propagated from mercurial documentation
 
    sections = [
 
                'alias',
 
                'auth',
 
                'decode/encode',
 
                'defaults',
 
                'diff',
 
                'email',
 
                'extensions',
 
                'format',
 
                'merge-patterns',
 
                'merge-tools',
 
                'hooks',
 
                'http_proxy',
 
                'smtp',
 
                'patch',
 
                'paths',
 
                'profiling',
 
                'server',
 
                'trusted',
 
                'ui',
 
                'web',
 
                ]
 

	
 
    baseui = ui.ui()
 
    cfg = config.config()
 
    cfg.read(path)
 
    if checkpaths:check_repo_dir(cfg.items('paths'))
 

	
 
    for section in sections:
 
        for k, v in cfg.items(section):
 
            baseui.setconfig(section, k, v)
 
        if checkpaths:check_repo_dir(cfg.items('paths'))                
 
              
 
        
 
    elif read_from == 'db':
 
        from pylons_app.model.meta import Session
 
        sa = Session()
 
            
 
        hg_ui = sa.query(HgAppUi).all()
 
        for ui_ in hg_ui:
 
            baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
 
        
 
    
 
    return baseui
 

	
 

	
 
def set_hg_app_config(config):
 
    config['hg_app_auth_realm'] = 'realm'
 
    config['hg_app_name'] = 'app name'
 

	
 
def invalidate_cache(name, *args):
 
    """Invalidates given name cache"""
 
    
pylons_app/model/db.py
Show inline comments
 
@@ -3,6 +3,21 @@ from sqlalchemy.orm import relation, bac
 
from sqlalchemy import *
 
from vcs.utils.lazy import LazyProperty
 

	
 
class HgAppSettings(Base):
 
    __tablename__ = 'hg_app_settings'
 
    __table_args__ = {'useexisting':True}
 
    app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    app_title = Column("app_title", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    app_auth_realm = Column("auth_realm", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
class HgAppUi(Base):
 
    __tablename__ = 'hg_app_ui'
 
    __table_args__ = {'useexisting':True}
 
    ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
 
    ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 
    ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
 

	
 
class User(Base): 
 
    __tablename__ = 'users'
 
    __table_args__ = {'useexisting':True}
pylons_app/websetup.py
Show inline comments
 
@@ -12,37 +12,11 @@ log = logging.getLogger(__name__)
 
ROOT = dn(dn(os.path.realpath(__file__)))
 
sys.path.append(ROOT)
 

	
 

	
 
def setup_repository():
 
    log.info('Seting up repositories.config')
 
    fname = 'repositories.config'
 
    
 
    try:
 
        tmpl = open(jn(ROOT, 'pylons_app', 'config', 'repositories.config_tmpl')).read()
 
    except IOError:
 
        raise
 
    
 
    path = raw_input('Specify valid full path to your repositories'
 
                    ' you can change this later in repositories.config file:')
 
    
 
    if not os.path.isdir(path):
 
        log.error('You entered wrong path')
 
        sys.exit()
 
    
 
    
 
    path = jn(path, '*') 
 
    dest_path = jn(ROOT, fname)
 
    f = open(dest_path, 'wb')
 
    f.write(tmpl % {'repo_location':path})
 
    f.close()
 
    log.info('created repositories.config in %s', dest_path)
 
        
 

	
 
def setup_app(command, conf, vars):
 
    """Place any commands to setup pylons_app here"""
 
    setup_repository()
 
    dbmanage = DbManage(log_sql=True)
 
    dbmanage.create_tables(override=True)
 
    dbmanage.config_prompt()
 
    dbmanage.admin_prompt()
 
    dbmanage.create_permissions()
 
    load_environment(conf.global_conf, conf.local_conf)
0 comments (0 inline, 0 general)