##// END OF EJS Templates
fixed problem with `Cannot operate on a closed database` error, by forcing NullPool when using sqlite database.
marcink -
r1300:882ac77d beta
parent child Browse files
Show More
@@ -1,85 +1,85
1 """Pylons environment configuration"""
1 """Pylons environment configuration"""
2
2
3 import os
3 import os
4 import logging
4 import logging
5
5
6 from mako.lookup import TemplateLookup
6 from mako.lookup import TemplateLookup
7 from pylons.configuration import PylonsConfig
7 from pylons.configuration import PylonsConfig
8 from pylons.error import handle_mako_error
8 from pylons.error import handle_mako_error
9 from sqlalchemy import engine_from_config
10
9
11 import rhodecode.lib.app_globals as app_globals
10 import rhodecode.lib.app_globals as app_globals
12 import rhodecode.lib.helpers
11 import rhodecode.lib.helpers
13
12
14 from rhodecode.config.routing import make_map
13 from rhodecode.config.routing import make_map
15 from rhodecode.lib import celerypylons
14 from rhodecode.lib import celerypylons
15 from rhodecode.lib import engine_from_config
16 from rhodecode.lib.timerproxy import TimerProxy
16 from rhodecode.lib.auth import set_available_permissions
17 from rhodecode.lib.auth import set_available_permissions
17 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
18 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
18 from rhodecode.model import init_model
19 from rhodecode.model import init_model
19 from rhodecode.model.scm import ScmModel
20 from rhodecode.model.scm import ScmModel
20 from rhodecode.lib.timerproxy import TimerProxy
21
21
22 log = logging.getLogger(__name__)
22 log = logging.getLogger(__name__)
23
23
24
24
25 def load_environment(global_conf, app_conf, initial=False):
25 def load_environment(global_conf, app_conf, initial=False):
26 """Configure the Pylons environment via the ``pylons.config``
26 """Configure the Pylons environment via the ``pylons.config``
27 object
27 object
28 """
28 """
29 config = PylonsConfig()
29 config = PylonsConfig()
30
30
31 # Pylons paths
31 # Pylons paths
32 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
32 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33 paths = dict(root=root,
33 paths = dict(root=root,
34 controllers=os.path.join(root, 'controllers'),
34 controllers=os.path.join(root, 'controllers'),
35 static_files=os.path.join(root, 'public'),
35 static_files=os.path.join(root, 'public'),
36 templates=[os.path.join(root, 'templates')])
36 templates=[os.path.join(root, 'templates')])
37
37
38 # Initialize config with the basic options
38 # Initialize config with the basic options
39 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
39 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
40
40
41 config['routes.map'] = make_map(config)
41 config['routes.map'] = make_map(config)
42 config['pylons.app_globals'] = app_globals.Globals(config)
42 config['pylons.app_globals'] = app_globals.Globals(config)
43 config['pylons.h'] = rhodecode.lib.helpers
43 config['pylons.h'] = rhodecode.lib.helpers
44
44
45 # Setup cache object as early as possible
45 # Setup cache object as early as possible
46 import pylons
46 import pylons
47 pylons.cache._push_object(config['pylons.app_globals'].cache)
47 pylons.cache._push_object(config['pylons.app_globals'].cache)
48
48
49 # Create the Mako TemplateLookup, with the default auto-escaping
49 # Create the Mako TemplateLookup, with the default auto-escaping
50 config['pylons.app_globals'].mako_lookup = TemplateLookup(
50 config['pylons.app_globals'].mako_lookup = TemplateLookup(
51 directories=paths['templates'],
51 directories=paths['templates'],
52 error_handler=handle_mako_error,
52 error_handler=handle_mako_error,
53 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
53 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
54 input_encoding='utf-8', default_filters=['escape'],
54 input_encoding='utf-8', default_filters=['escape'],
55 imports=['from webhelpers.html import escape'])
55 imports=['from webhelpers.html import escape'])
56
56
57 #sets the c attribute access when don't existing attribute are accessed
57 #sets the c attribute access when don't existing attribute are accessed
58 config['pylons.strict_tmpl_context'] = True
58 config['pylons.strict_tmpl_context'] = True
59 test = os.path.split(config['__file__'])[-1] == 'test.ini'
59 test = os.path.split(config['__file__'])[-1] == 'test.ini'
60 if test:
60 if test:
61 from rhodecode.lib.utils import create_test_env, create_test_index
61 from rhodecode.lib.utils import create_test_env, create_test_index
62 from rhodecode.tests import TESTS_TMP_PATH
62 from rhodecode.tests import TESTS_TMP_PATH
63 create_test_env(TESTS_TMP_PATH, config)
63 create_test_env(TESTS_TMP_PATH, config)
64 create_test_index(TESTS_TMP_PATH, True)
64 create_test_index(TESTS_TMP_PATH, True)
65
65
66 #MULTIPLE DB configs
66 #MULTIPLE DB configs
67 # Setup the SQLAlchemy database engine
67 # Setup the SQLAlchemy database engine
68 if config['debug'] and not test:
68 if config['debug'] and not test:
69 #use query time debugging.
69 #use query time debugging.
70 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
70 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
71 proxy=TimerProxy())
71 proxy=TimerProxy())
72 else:
72 else:
73 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
73 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
74
74
75 init_model(sa_engine_db1)
75 init_model(sa_engine_db1)
76
76
77 repos_path = make_ui('db').configitems('paths')[0][1]
77 repos_path = make_ui('db').configitems('paths')[0][1]
78 repo2db_mapper(ScmModel().repo_scan(repos_path))
78 repo2db_mapper(ScmModel().repo_scan(repos_path))
79 set_available_permissions(config)
79 set_available_permissions(config)
80 config['base_path'] = repos_path
80 config['base_path'] = repos_path
81 set_rhodecode_config(config)
81 set_rhodecode_config(config)
82 # CONFIGURATION OPTIONS HERE (note: all config options will override
82 # CONFIGURATION OPTIONS HERE (note: all config options will override
83 # any Pylons config options)
83 # any Pylons config options)
84
84
85 return config
85 return config
@@ -1,81 +1,100
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.__init__
3 rhodecode.lib.__init__
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Some simple helper functions
6 Some simple helper functions
7
7
8 :created_on: Jan 5, 2011
8 :created_on: Jan 5, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26
26
27 def str2bool(_str):
27 def str2bool(_str):
28 """
28 """
29 returs True/False value from given string, it tries to translate the
29 returs True/False value from given string, it tries to translate the
30 string into boolean
30 string into boolean
31
31
32 :param _str: string value to translate into boolean
32 :param _str: string value to translate into boolean
33 :rtype: boolean
33 :rtype: boolean
34 :returns: boolean from given string
34 :returns: boolean from given string
35 """
35 """
36 if _str is None:
36 if _str is None:
37 return False
37 return False
38 if _str in (True, False):
38 if _str in (True, False):
39 return _str
39 return _str
40 _str = str(_str).strip().lower()
40 _str = str(_str).strip().lower()
41 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
41 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
42
42
43
43
44 def generate_api_key(username, salt=None):
44 def generate_api_key(username, salt=None):
45 """
45 """
46 Generates unique API key for given username,if salt is not given
46 Generates unique API key for given username,if salt is not given
47 it'll be generated from some random string
47 it'll be generated from some random string
48
48
49 :param username: username as string
49 :param username: username as string
50 :param salt: salt to hash generate KEY
50 :param salt: salt to hash generate KEY
51 :rtype: str
51 :rtype: str
52 :returns: sha1 hash from username+salt
52 :returns: sha1 hash from username+salt
53 """
53 """
54 from tempfile import _RandomNameSequence
54 from tempfile import _RandomNameSequence
55 import hashlib
55 import hashlib
56
56
57 if salt is None:
57 if salt is None:
58 salt = _RandomNameSequence().next()
58 salt = _RandomNameSequence().next()
59
59
60 return hashlib.sha1(username + salt).hexdigest()
60 return hashlib.sha1(username + salt).hexdigest()
61
61
62
62
63 def safe_unicode(_str, from_encoding='utf8'):
63 def safe_unicode(_str, from_encoding='utf8'):
64 """
64 """
65 safe unicode function. In case of UnicodeDecode error we try to return
65 safe unicode function. In case of UnicodeDecode error we try to return
66 unicode with errors replace
66 unicode with errors replace
67
67
68 :param _str: string to decode
68 :param _str: string to decode
69 :rtype: unicode
69 :rtype: unicode
70 :returns: unicode object
70 :returns: unicode object
71 """
71 """
72
72
73 if isinstance(_str, unicode):
73 if isinstance(_str, unicode):
74 return _str
74 return _str
75
75
76 try:
76 try:
77 u_str = unicode(_str, from_encoding)
77 u_str = unicode(_str, from_encoding)
78 except UnicodeDecodeError:
78 except UnicodeDecodeError:
79 u_str = unicode(_str, from_encoding, 'replace')
79 u_str = unicode(_str, from_encoding, 'replace')
80
80
81 return u_str
81 return u_str
82
83
84 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
85 """
86 Custom engine_from_config functions that makes sure we use NullPool for
87 file based sqlite databases. This prevents errors on sqlite.
88
89 """
90 from sqlalchemy import engine_from_config as efc
91 from sqlalchemy.pool import NullPool
92
93 url = configuration[prefix + 'url']
94
95 if url.startswith('sqlite'):
96 kwargs.update({'poolclass':NullPool})
97
98 return efc(configuration, prefix, **kwargs)
99
100
General Comments 0
You need to be logged in to leave comments. Login now