##// END OF EJS Templates
Made config file free configuration based on database and capable of beeing manage via application settings + some code cleanups
marcink -
r341:1ef52a70 default
parent child Browse files
Show More
@@ -4,7 +4,7 b' from pylons.configuration import PylonsC'
4 from pylons.error import handle_mako_error
4 from pylons.error import handle_mako_error
5 from pylons_app.config.routing import make_map
5 from pylons_app.config.routing import make_map
6 from pylons_app.lib.auth import set_available_permissions, set_base_path
6 from pylons_app.lib.auth import set_available_permissions, set_base_path
7 from pylons_app.lib.utils import repo2db_mapper
7 from pylons_app.lib.utils import repo2db_mapper, make_ui, set_hg_app_config
8 from pylons_app.model import init_model
8 from pylons_app.model import init_model
9 from pylons_app.model.hg_model import _get_repos_cached_initial
9 from pylons_app.model.hg_model import _get_repos_cached_initial
10 from sqlalchemy import engine_from_config
10 from sqlalchemy import engine_from_config
@@ -61,9 +61,12 b' def load_environment(global_conf, app_co'
61 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
61 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
62
62
63 init_model(sa_engine_db1)
63 init_model(sa_engine_db1)
64 config['pylons.app_globals'].baseui = make_ui('db')
65
64 repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals']))
66 repo2db_mapper(_get_repos_cached_initial(config['pylons.app_globals']))
65 set_available_permissions(config)
67 set_available_permissions(config)
66 set_base_path(config)
68 set_base_path(config)
69 set_hg_app_config(config)
67 # CONFIGURATION OPTIONS HERE (note: all config options will override
70 # CONFIGURATION OPTIONS HERE (note: all config options will override
68 # any Pylons config options)
71 # any Pylons config options)
69
72
@@ -41,7 +41,6 b' def make_app(global_conf, full_stack=Tru'
41 app = SessionMiddleware(app, config)
41 app = SessionMiddleware(app, config)
42
42
43 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
43 # CUSTOM MIDDLEWARE HERE (filtered by error handling middlewares)
44 #set the https based on HTTP_X_URL_SCHEME
45
44
46 app = SimpleHg(app, config)
45 app = SimpleHg(app, config)
47
46
@@ -70,8 +70,6 b' class SettingsController(BaseController)'
70 )
70 )
71
71
72 def update(self, repo_name):
72 def update(self, repo_name):
73 print request.POST
74 print 'x' * 110
75 repo_model = RepoModel()
73 repo_model = RepoModel()
76 _form = RepoSettingsForm(edit=True)()
74 _form = RepoSettingsForm(edit=True)()
77 try:
75 try:
@@ -2,10 +2,9 b''
2
2
3 from beaker.cache import CacheManager
3 from beaker.cache import CacheManager
4 from beaker.util import parse_cache_config_options
4 from beaker.util import parse_cache_config_options
5 from pylons_app.lib.utils import make_ui
5 from vcs.utils.lazy import LazyProperty
6
6
7 class Globals(object):
7 class Globals(object):
8
9 """Globals acts as a container for objects available throughout the
8 """Globals acts as a container for objects available throughout the
10 life of the application
9 life of the application
11
10
@@ -18,8 +17,17 b' class Globals(object):'
18
17
19 """
18 """
20 self.cache = CacheManager(**parse_cache_config_options(config))
19 self.cache = CacheManager(**parse_cache_config_options(config))
21 self.baseui = make_ui(config['hg_app_repo_conf'])
22 self.paths = self.baseui.configitems('paths')
23 self.base_path = self.paths[0][1].replace('*', '')
24 self.changeset_annotation_colors = {}
20 self.changeset_annotation_colors = {}
25 self.available_permissions = None # propagated after init_model
21 self.available_permissions = None # propagated after init_model
22 self.app_title = None # propagated after init_model
23 self.baseui = None # propagated after init_model
24
25 @LazyProperty
26 def paths(self):
27 if self.baseui:
28 return self.baseui.configitems('paths')
29
30 @LazyProperty
31 def base_path(self):
32 if self.baseui:
33 return self.paths[0][1].replace('*', '')
@@ -33,7 +33,7 b' sys.path.append(ROOT)'
33
33
34 from pylons_app.lib.auth import get_crypt_password
34 from pylons_app.lib.auth import get_crypt_password
35 from pylons_app.model import init_model
35 from pylons_app.model import init_model
36 from pylons_app.model.db import User, Permission
36 from pylons_app.model.db import User, Permission, HgAppUi
37 from pylons_app.model.meta import Session, Base
37 from pylons_app.model.meta import Session, Base
38 from sqlalchemy.engine import create_engine
38 from sqlalchemy.engine import create_engine
39 import logging
39 import logging
@@ -79,7 +79,62 b' class DbManage(object):'
79 username = raw_input('Specify admin username:')
79 username = raw_input('Specify admin username:')
80 password = getpass.getpass('Specify admin password:')
80 password = getpass.getpass('Specify admin password:')
81 self.create_user(username, password, True)
81 self.create_user(username, password, True)
82
83 def config_prompt(self):
84 log.info('Seting up repositories.config')
82
85
86
87 path = raw_input('Specify valid full path to your repositories'
88 ' you can change this later application settings:')
89
90 if not os.path.isdir(path):
91 log.error('You entered wrong path')
92 sys.exit()
93
94 hooks = HgAppUi()
95 hooks.ui_section = 'hooks'
96 hooks.ui_key = 'changegroup'
97 hooks.ui_value = 'hg update >&2'
98
99 web1 = HgAppUi()
100 web1.ui_section = 'web'
101 web1.ui_key = 'push_ssl'
102 web1.ui_value = 'false'
103
104 web2 = HgAppUi()
105 web2.ui_section = 'web'
106 web2.ui_key = 'allow_archive'
107 web2.ui_value = 'gz zip bz2'
108
109 web3 = HgAppUi()
110 web3.ui_section = 'web'
111 web3.ui_key = 'allow_push'
112 web3.ui_value = '*'
113
114 web4 = HgAppUi()
115 web4.ui_section = 'web'
116 web4.ui_key = 'baseurl'
117 web4.ui_value = '/'
118
119 paths = HgAppUi()
120 paths.ui_section = 'paths'
121 paths.ui_key = '/'
122 paths.ui_value = os.path.join(path, '*')
123
124
125 try:
126 self.sa.add(hooks)
127 self.sa.add(web1)
128 self.sa.add(web2)
129 self.sa.add(web3)
130 self.sa.add(web4)
131 self.sa.add(paths)
132 self.sa.commit()
133 except:
134 self.sa.rollback()
135 raise
136 log.info('created ui config')
137
83 def create_user(self, username, password, admin=False):
138 def create_user(self, username, password, admin=False):
84
139
85 log.info('creating default user')
140 log.info('creating default user')
@@ -93,8 +148,6 b' class DbManage(object):'
93 def_user.admin = False
148 def_user.admin = False
94 def_user.active = False
149 def_user.active = False
95
150
96 self.sa.add(def_user)
97
98 log.info('creating administrator user %s', username)
151 log.info('creating administrator user %s', username)
99 new_user = User()
152 new_user = User()
100 new_user.username = username
153 new_user.username = username
@@ -106,6 +159,7 b' class DbManage(object):'
106 new_user.active = True
159 new_user.active = True
107
160
108 try:
161 try:
162 self.sa.add(def_user)
109 self.sa.add(new_user)
163 self.sa.add(new_user)
110 self.sa.commit()
164 self.sa.commit()
111 except:
165 except:
@@ -50,7 +50,7 b' class SimpleHg(object):'
50 self.application = application
50 self.application = application
51 self.config = config
51 self.config = config
52 #authenticate this mercurial request using
52 #authenticate this mercurial request using
53 realm = '%s %s' % (self.config['hg_app_name'], 'mercurial repository')
53 realm = self.config['hg_app_auth_realm']
54 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
54 self.authenticate = AuthBasicAuthenticator(realm, authfunc)
55
55
56 def __call__(self, environ, start_response):
56 def __call__(self, environ, start_response):
@@ -111,14 +111,13 b' class SimpleHg(object):'
111 # MERCURIAL REQUEST HANDLING
111 # MERCURIAL REQUEST HANDLING
112 #===================================================================
112 #===================================================================
113 environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
113 environ['PATH_INFO'] = '/'#since we wrap into hgweb, reset the path
114 self.baseui = make_ui(self.config['hg_app_repo_conf'])
114 self.baseui = make_ui('db')
115 self.basepath = self.config['base_path']
115 self.basepath = self.config['base_path']
116 self.repo_path = os.path.join(self.basepath, repo_name)
116 self.repo_path = os.path.join(self.basepath, repo_name)
117
117
118 #quick check if that dir exists...
118 #quick check if that dir exists...
119 if check_repo_fast(repo_name, self.basepath):
119 if check_repo_fast(repo_name, self.basepath):
120 return HTTPNotFound()(environ, start_response)
120 return HTTPNotFound()(environ, start_response)
121
122 try:
121 try:
123 app = wsgiapplication(self.__make_app)
122 app = wsgiapplication(self.__make_app)
124 except RepoError as e:
123 except RepoError as e:
@@ -155,7 +154,7 b' class SimpleHg(object):'
155 return chain(org_response, custom_messages(messages))
154 return chain(org_response, custom_messages(messages))
156
155
157 def __make_app(self):
156 def __make_app(self):
158 hgserve = hgweb(self.repo_path)
157 hgserve = hgweb(str(self.repo_path), baseui=self.baseui)
159 return self.__load_web_settings(hgserve)
158 return self.__load_web_settings(hgserve)
160
159
161 def __get_environ_user(self, environ):
160 def __get_environ_user(self, environ):
@@ -214,10 +213,12 b' class SimpleHg(object):'
214
213
215
214
216 def __load_web_settings(self, hgserve):
215 def __load_web_settings(self, hgserve):
217 repoui = make_ui(os.path.join(self.repo_path, '.hg', 'hgrc'), False)
218 #set the global ui for hgserve
216 #set the global ui for hgserve
219 hgserve.repo.ui = self.baseui
217 hgserve.repo.ui = self.baseui
220
218
219 hgrc = os.path.join(self.repo_path, '.hg', 'hgrc')
220 repoui = make_ui('file', hgrc, False)
221
221 if repoui:
222 if repoui:
222 #set the repository based config
223 #set the repository based config
223 hgserve.repo.ui = repoui
224 hgserve.repo.ui = repoui
@@ -27,7 +27,7 b' import os'
27 import logging
27 import logging
28 from mercurial import ui, config, hg
28 from mercurial import ui, config, hg
29 from mercurial.error import RepoError
29 from mercurial.error import RepoError
30 from pylons_app.model.db import Repository, User
30 from pylons_app.model.db import Repository, User, HgAppUi
31 log = logging.getLogger(__name__)
31 log = logging.getLogger(__name__)
32
32
33
33
@@ -75,53 +75,58 b' def check_repo(repo_name, base_path, ver'
75 log.info('%s repo is free for creation', repo_name)
75 log.info('%s repo is free for creation', repo_name)
76 return True
76 return True
77
77
78 def make_ui(path=None, checkpaths=True):
78 def make_ui(read_from='file', path=None, checkpaths=True):
79 """
79 """
80 A funcion that will read python rc files and make an ui from read options
80 A function that will read python rc files or database
81 and make an mercurial ui object from read options
81
82
82 @param path: path to mercurial config file
83 @param path: path to mercurial config file
84 @param checkpaths: check the path
85 @param read_from: read from 'file' or 'db'
83 """
86 """
84 if not path:
85 log.error('repos config path is empty !')
86
87 if not os.path.isfile(path):
88 log.warning('Unable to read config file %s' % path)
89 return False
90 #propagated from mercurial documentation
87 #propagated from mercurial documentation
91 sections = [
88 sections = ['alias', 'auth',
92 'alias',
89 'decode/encode', 'defaults',
93 'auth',
90 'diff', 'email',
94 'decode/encode',
91 'extensions', 'format',
95 'defaults',
92 'merge-patterns', 'merge-tools',
96 'diff',
93 'hooks', 'http_proxy',
97 'email',
94 'smtp', 'patch',
98 'extensions',
95 'paths', 'profiling',
99 'format',
96 'server', 'trusted',
100 'merge-patterns',
97 'ui', 'web', ]
101 'merge-tools',
98 baseui = ui.ui()
102 'hooks',
103 'http_proxy',
104 'smtp',
105 'patch',
106 'paths',
107 'profiling',
108 'server',
109 'trusted',
110 'ui',
111 'web',
112 ]
113
99
114 baseui = ui.ui()
100
115 cfg = config.config()
101 if read_from == 'file':
116 cfg.read(path)
102 if not os.path.isfile(path):
117 if checkpaths:check_repo_dir(cfg.items('paths'))
103 log.warning('Unable to read config file %s' % path)
118
104 return False
119 for section in sections:
105
120 for k, v in cfg.items(section):
106 cfg = config.config()
121 baseui.setconfig(section, k, v)
107 cfg.read(path)
108 for section in sections:
109 for k, v in cfg.items(section):
110 baseui.setconfig(section, k, v)
111 if checkpaths:check_repo_dir(cfg.items('paths'))
112
113
114 elif read_from == 'db':
115 from pylons_app.model.meta import Session
116 sa = Session()
117
118 hg_ui = sa.query(HgAppUi).all()
119 for ui_ in hg_ui:
120 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
121
122
122
123 return baseui
123 return baseui
124
124
125
126 def set_hg_app_config(config):
127 config['hg_app_auth_realm'] = 'realm'
128 config['hg_app_name'] = 'app name'
129
125 def invalidate_cache(name, *args):
130 def invalidate_cache(name, *args):
126 """Invalidates given name cache"""
131 """Invalidates given name cache"""
127
132
@@ -3,6 +3,21 b' from sqlalchemy.orm import relation, bac'
3 from sqlalchemy import *
3 from sqlalchemy import *
4 from vcs.utils.lazy import LazyProperty
4 from vcs.utils.lazy import LazyProperty
5
5
6 class HgAppSettings(Base):
7 __tablename__ = 'hg_app_settings'
8 __table_args__ = {'useexisting':True}
9 app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
10 app_title = Column("app_title", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
11 app_auth_realm = Column("auth_realm", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
12
13 class HgAppUi(Base):
14 __tablename__ = 'hg_app_ui'
15 __table_args__ = {'useexisting':True}
16 ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
17 ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
18 ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
19 ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
20
6 class User(Base):
21 class User(Base):
7 __tablename__ = 'users'
22 __tablename__ = 'users'
8 __table_args__ = {'useexisting':True}
23 __table_args__ = {'useexisting':True}
@@ -12,37 +12,11 b' log = logging.getLogger(__name__)'
12 ROOT = dn(dn(os.path.realpath(__file__)))
12 ROOT = dn(dn(os.path.realpath(__file__)))
13 sys.path.append(ROOT)
13 sys.path.append(ROOT)
14
14
15
16 def setup_repository():
17 log.info('Seting up repositories.config')
18 fname = 'repositories.config'
19
20 try:
21 tmpl = open(jn(ROOT, 'pylons_app', 'config', 'repositories.config_tmpl')).read()
22 except IOError:
23 raise
24
25 path = raw_input('Specify valid full path to your repositories'
26 ' you can change this later in repositories.config file:')
27
28 if not os.path.isdir(path):
29 log.error('You entered wrong path')
30 sys.exit()
31
32
33 path = jn(path, '*')
34 dest_path = jn(ROOT, fname)
35 f = open(dest_path, 'wb')
36 f.write(tmpl % {'repo_location':path})
37 f.close()
38 log.info('created repositories.config in %s', dest_path)
39
40
41 def setup_app(command, conf, vars):
15 def setup_app(command, conf, vars):
42 """Place any commands to setup pylons_app here"""
16 """Place any commands to setup pylons_app here"""
43 setup_repository()
44 dbmanage = DbManage(log_sql=True)
17 dbmanage = DbManage(log_sql=True)
45 dbmanage.create_tables(override=True)
18 dbmanage.create_tables(override=True)
19 dbmanage.config_prompt()
46 dbmanage.admin_prompt()
20 dbmanage.admin_prompt()
47 dbmanage.create_permissions()
21 dbmanage.create_permissions()
48 load_environment(conf.global_conf, conf.local_conf)
22 load_environment(conf.global_conf, conf.local_conf)
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now