##// END OF EJS Templates
settings: use cache on whole result not just the query since it's the computation...
marcink -
r259:f75d6c26 default
parent child Browse files
Show More
@@ -1,681 +1,690 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 RhodeCode GmbH
3 # Copyright (C) 2010-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import hashlib
21 import hashlib
22 import logging
22 import logging
23 from collections import namedtuple
23 from collections import namedtuple
24 from functools import wraps
24 from functools import wraps
25
25
26 from rhodecode.lib import caches
26 from rhodecode.lib.caching_query import FromCache
27 from rhodecode.lib.caching_query import FromCache
27 from rhodecode.lib.utils2 import (
28 from rhodecode.lib.utils2 import (
28 Optional, AttributeDict, safe_str, remove_prefix, str2bool)
29 Optional, AttributeDict, safe_str, remove_prefix, str2bool)
29 from rhodecode.model import BaseModel
30 from rhodecode.model import BaseModel
30 from rhodecode.model.db import (
31 from rhodecode.model.db import (
31 RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi, RhodeCodeSetting)
32 RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi, RhodeCodeSetting)
32 from rhodecode.model.meta import Session
33 from rhodecode.model.meta import Session
33
34
34
35
35 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
36
37
37
38
38 UiSetting = namedtuple(
39 UiSetting = namedtuple(
39 'UiSetting', ['section', 'key', 'value', 'active'])
40 'UiSetting', ['section', 'key', 'value', 'active'])
40
41
41 SOCIAL_PLUGINS_LIST = ['github', 'bitbucket', 'twitter', 'google']
42 SOCIAL_PLUGINS_LIST = ['github', 'bitbucket', 'twitter', 'google']
42
43
43
44
44 class SettingNotFound(Exception):
45 class SettingNotFound(Exception):
45 def __init__(self):
46 def __init__(self):
46 super(SettingNotFound, self).__init__('Setting is not found')
47 super(SettingNotFound, self).__init__('Setting is not found')
47
48
48
49
49 class SettingsModel(BaseModel):
50 class SettingsModel(BaseModel):
50 BUILTIN_HOOKS = (
51 BUILTIN_HOOKS = (
51 RhodeCodeUi.HOOK_REPO_SIZE, RhodeCodeUi.HOOK_PUSH,
52 RhodeCodeUi.HOOK_REPO_SIZE, RhodeCodeUi.HOOK_PUSH,
52 RhodeCodeUi.HOOK_PRE_PUSH, RhodeCodeUi.HOOK_PULL,
53 RhodeCodeUi.HOOK_PRE_PUSH, RhodeCodeUi.HOOK_PULL,
53 RhodeCodeUi.HOOK_PRE_PULL)
54 RhodeCodeUi.HOOK_PRE_PULL)
54 HOOKS_SECTION = 'hooks'
55 HOOKS_SECTION = 'hooks'
55
56
56 def __init__(self, sa=None, repo=None):
57 def __init__(self, sa=None, repo=None):
57 self.repo = repo
58 self.repo = repo
58 self.UiDbModel = RepoRhodeCodeUi if repo else RhodeCodeUi
59 self.UiDbModel = RepoRhodeCodeUi if repo else RhodeCodeUi
59 self.SettingsDbModel = (
60 self.SettingsDbModel = (
60 RepoRhodeCodeSetting if repo else RhodeCodeSetting)
61 RepoRhodeCodeSetting if repo else RhodeCodeSetting)
61 super(SettingsModel, self).__init__(sa)
62 super(SettingsModel, self).__init__(sa)
62
63
63 def get_ui_by_key(self, key):
64 def get_ui_by_key(self, key):
64 q = self.UiDbModel.query()
65 q = self.UiDbModel.query()
65 q = q.filter(self.UiDbModel.ui_key == key)
66 q = q.filter(self.UiDbModel.ui_key == key)
66 q = self._filter_by_repo(RepoRhodeCodeUi, q)
67 q = self._filter_by_repo(RepoRhodeCodeUi, q)
67 return q.scalar()
68 return q.scalar()
68
69
69 def get_ui_by_section(self, section):
70 def get_ui_by_section(self, section):
70 q = self.UiDbModel.query()
71 q = self.UiDbModel.query()
71 q = q.filter(self.UiDbModel.ui_section == section)
72 q = q.filter(self.UiDbModel.ui_section == section)
72 q = self._filter_by_repo(RepoRhodeCodeUi, q)
73 q = self._filter_by_repo(RepoRhodeCodeUi, q)
73 return q.all()
74 return q.all()
74
75
75 def get_ui_by_section_and_key(self, section, key):
76 def get_ui_by_section_and_key(self, section, key):
76 q = self.UiDbModel.query()
77 q = self.UiDbModel.query()
77 q = q.filter(self.UiDbModel.ui_section == section)
78 q = q.filter(self.UiDbModel.ui_section == section)
78 q = q.filter(self.UiDbModel.ui_key == key)
79 q = q.filter(self.UiDbModel.ui_key == key)
79 q = self._filter_by_repo(RepoRhodeCodeUi, q)
80 q = self._filter_by_repo(RepoRhodeCodeUi, q)
80 return q.scalar()
81 return q.scalar()
81
82
82 def get_ui(self, section=None, key=None):
83 def get_ui(self, section=None, key=None):
83 q = self.UiDbModel.query()
84 q = self.UiDbModel.query()
84 q = self._filter_by_repo(RepoRhodeCodeUi, q)
85 q = self._filter_by_repo(RepoRhodeCodeUi, q)
85
86
86 if section:
87 if section:
87 q = q.filter(self.UiDbModel.ui_section == section)
88 q = q.filter(self.UiDbModel.ui_section == section)
88 if key:
89 if key:
89 q = q.filter(self.UiDbModel.ui_key == key)
90 q = q.filter(self.UiDbModel.ui_key == key)
90
91
91 # TODO: mikhail: add caching
92 # TODO: mikhail: add caching
92 result = [
93 result = [
93 UiSetting(
94 UiSetting(
94 section=safe_str(r.ui_section), key=safe_str(r.ui_key),
95 section=safe_str(r.ui_section), key=safe_str(r.ui_key),
95 value=safe_str(r.ui_value), active=r.ui_active
96 value=safe_str(r.ui_value), active=r.ui_active
96 )
97 )
97 for r in q.all()
98 for r in q.all()
98 ]
99 ]
99 return result
100 return result
100
101
101 def get_builtin_hooks(self):
102 def get_builtin_hooks(self):
102 q = self.UiDbModel.query()
103 q = self.UiDbModel.query()
103 q = q.filter(self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
104 q = q.filter(self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
104 return self._get_hooks(q)
105 return self._get_hooks(q)
105
106
106 def get_custom_hooks(self):
107 def get_custom_hooks(self):
107 q = self.UiDbModel.query()
108 q = self.UiDbModel.query()
108 q = q.filter(~self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
109 q = q.filter(~self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
109 return self._get_hooks(q)
110 return self._get_hooks(q)
110
111
111 def create_ui_section_value(self, section, val, key=None, active=True):
112 def create_ui_section_value(self, section, val, key=None, active=True):
112 new_ui = self.UiDbModel()
113 new_ui = self.UiDbModel()
113 new_ui.ui_section = section
114 new_ui.ui_section = section
114 new_ui.ui_value = val
115 new_ui.ui_value = val
115 new_ui.ui_active = active
116 new_ui.ui_active = active
116
117
117 if self.repo:
118 if self.repo:
118 repo = self._get_repo(self.repo)
119 repo = self._get_repo(self.repo)
119 repository_id = repo.repo_id
120 repository_id = repo.repo_id
120 new_ui.repository_id = repository_id
121 new_ui.repository_id = repository_id
121
122
122 if not key:
123 if not key:
123 # keys are unique so they need appended info
124 # keys are unique so they need appended info
124 if self.repo:
125 if self.repo:
125 key = hashlib.sha1(
126 key = hashlib.sha1(
126 '{}{}{}'.format(section, val, repository_id)).hexdigest()
127 '{}{}{}'.format(section, val, repository_id)).hexdigest()
127 else:
128 else:
128 key = hashlib.sha1('{}{}'.format(section, val)).hexdigest()
129 key = hashlib.sha1('{}{}'.format(section, val)).hexdigest()
129
130
130 new_ui.ui_key = key
131 new_ui.ui_key = key
131
132
132 Session().add(new_ui)
133 Session().add(new_ui)
133 return new_ui
134 return new_ui
134
135
135 def create_or_update_hook(self, key, value):
136 def create_or_update_hook(self, key, value):
136 ui = (
137 ui = (
137 self.get_ui_by_section_and_key(self.HOOKS_SECTION, key) or
138 self.get_ui_by_section_and_key(self.HOOKS_SECTION, key) or
138 self.UiDbModel())
139 self.UiDbModel())
139 ui.ui_section = self.HOOKS_SECTION
140 ui.ui_section = self.HOOKS_SECTION
140 ui.ui_active = True
141 ui.ui_active = True
141 ui.ui_key = key
142 ui.ui_key = key
142 ui.ui_value = value
143 ui.ui_value = value
143
144
144 if self.repo:
145 if self.repo:
145 repo = self._get_repo(self.repo)
146 repo = self._get_repo(self.repo)
146 repository_id = repo.repo_id
147 repository_id = repo.repo_id
147 ui.repository_id = repository_id
148 ui.repository_id = repository_id
148
149
149 Session().add(ui)
150 Session().add(ui)
150 return ui
151 return ui
151
152
152 def delete_ui(self, id_):
153 def delete_ui(self, id_):
153 ui = self.UiDbModel.get(id_)
154 ui = self.UiDbModel.get(id_)
154 if not ui:
155 if not ui:
155 raise SettingNotFound()
156 raise SettingNotFound()
156 Session().delete(ui)
157 Session().delete(ui)
157
158
158 def get_setting_by_name(self, name):
159 def get_setting_by_name(self, name):
159 q = self._get_settings_query()
160 q = self._get_settings_query()
160 q = q.filter(self.SettingsDbModel.app_settings_name == name)
161 q = q.filter(self.SettingsDbModel.app_settings_name == name)
161 return q.scalar()
162 return q.scalar()
162
163
163 def create_or_update_setting(
164 def create_or_update_setting(
164 self, name, val=Optional(''), type_=Optional('unicode')):
165 self, name, val=Optional(''), type_=Optional('unicode')):
165 """
166 """
166 Creates or updates RhodeCode setting. If updates is triggered it will
167 Creates or updates RhodeCode setting. If updates is triggered it will
167 only update parameters that are explicityl set Optional instance will
168 only update parameters that are explicityl set Optional instance will
168 be skipped
169 be skipped
169
170
170 :param name:
171 :param name:
171 :param val:
172 :param val:
172 :param type_:
173 :param type_:
173 :return:
174 :return:
174 """
175 """
175
176
176 res = self.get_setting_by_name(name)
177 res = self.get_setting_by_name(name)
177 repo = self._get_repo(self.repo) if self.repo else None
178 repo = self._get_repo(self.repo) if self.repo else None
178
179
179 if not res:
180 if not res:
180 val = Optional.extract(val)
181 val = Optional.extract(val)
181 type_ = Optional.extract(type_)
182 type_ = Optional.extract(type_)
182
183
183 args = (
184 args = (
184 (repo.repo_id, name, val, type_)
185 (repo.repo_id, name, val, type_)
185 if repo else (name, val, type_))
186 if repo else (name, val, type_))
186 res = self.SettingsDbModel(*args)
187 res = self.SettingsDbModel(*args)
187
188
188 else:
189 else:
189 if self.repo:
190 if self.repo:
190 res.repository_id = repo.repo_id
191 res.repository_id = repo.repo_id
191
192
192 res.app_settings_name = name
193 res.app_settings_name = name
193 if not isinstance(type_, Optional):
194 if not isinstance(type_, Optional):
194 # update if set
195 # update if set
195 res.app_settings_type = type_
196 res.app_settings_type = type_
196 if not isinstance(val, Optional):
197 if not isinstance(val, Optional):
197 # update if set
198 # update if set
198 res.app_settings_value = val
199 res.app_settings_value = val
199
200
200 Session.add(res)
201 Session.add(res)
201 return res
202 return res
202
203
203 def get_all_settings(self, cache=False):
204 def get_all_settings(self, cache=False):
205 def _compute():
204 q = self._get_settings_query()
206 q = self._get_settings_query()
205 if cache:
206 repo = self._get_repo(self.repo) if self.repo else None
207 cache_key = (
208 "get_repo_{}_settings".format(repo.repo_id)
209 if repo else "get_hg_settings")
210 q = q.options(FromCache("sql_cache_short", cache_key))
211
212 if not q:
207 if not q:
213 raise Exception('Could not get application settings !')
208 raise Exception('Could not get application settings !')
214
209
215 settings = {
210 settings = {
216 'rhodecode_' + result.app_settings_name: result.app_settings_value
211 'rhodecode_' + result.app_settings_name: result.app_settings_value
217 for result in q
212 for result in q
218 }
213 }
219 return settings
214 return settings
220
215
216 if cache:
217 repo = self._get_repo(self.repo) if self.repo else None
218 namespace = 'rhodecode_settings'
219 cache_manager = caches.get_cache_manager(
220 'sql_cache_short', namespace)
221 _cache_key = (
222 "get_repo_{}_settings".format(repo.repo_id)
223 if repo else "get_app_settings")
224
225 return cache_manager.get(_cache_key, createfunc=_compute)
226
227 else:
228 return _compute()
229
221 def get_auth_settings(self):
230 def get_auth_settings(self):
222 q = self._get_settings_query()
231 q = self._get_settings_query()
223 q = q.filter(
232 q = q.filter(
224 self.SettingsDbModel.app_settings_name.startswith('auth_'))
233 self.SettingsDbModel.app_settings_name.startswith('auth_'))
225 rows = q.all()
234 rows = q.all()
226 auth_settings = {
235 auth_settings = {
227 row.app_settings_name: row.app_settings_value for row in rows}
236 row.app_settings_name: row.app_settings_value for row in rows}
228 return auth_settings
237 return auth_settings
229
238
230 def get_auth_plugins(self):
239 def get_auth_plugins(self):
231 auth_plugins = self.get_setting_by_name("auth_plugins")
240 auth_plugins = self.get_setting_by_name("auth_plugins")
232 return auth_plugins.app_settings_value
241 return auth_plugins.app_settings_value
233
242
234 def get_default_repo_settings(self, strip_prefix=False):
243 def get_default_repo_settings(self, strip_prefix=False):
235 q = self._get_settings_query()
244 q = self._get_settings_query()
236 q = q.filter(
245 q = q.filter(
237 self.SettingsDbModel.app_settings_name.startswith('default_'))
246 self.SettingsDbModel.app_settings_name.startswith('default_'))
238 rows = q.all()
247 rows = q.all()
239
248
240 result = {}
249 result = {}
241 for row in rows:
250 for row in rows:
242 key = row.app_settings_name
251 key = row.app_settings_name
243 if strip_prefix:
252 if strip_prefix:
244 key = remove_prefix(key, prefix='default_')
253 key = remove_prefix(key, prefix='default_')
245 result.update({key: row.app_settings_value})
254 result.update({key: row.app_settings_value})
246 return result
255 return result
247
256
248 def get_repo(self):
257 def get_repo(self):
249 repo = self._get_repo(self.repo)
258 repo = self._get_repo(self.repo)
250 if not repo:
259 if not repo:
251 raise Exception(
260 raise Exception(
252 'Repository {} cannot be found'.format(self.repo))
261 'Repository {} cannot be found'.format(self.repo))
253 return repo
262 return repo
254
263
255 def _filter_by_repo(self, model, query):
264 def _filter_by_repo(self, model, query):
256 if self.repo:
265 if self.repo:
257 repo = self.get_repo()
266 repo = self.get_repo()
258 query = query.filter(model.repository_id == repo.repo_id)
267 query = query.filter(model.repository_id == repo.repo_id)
259 return query
268 return query
260
269
261 def _get_hooks(self, query):
270 def _get_hooks(self, query):
262 query = query.filter(self.UiDbModel.ui_section == self.HOOKS_SECTION)
271 query = query.filter(self.UiDbModel.ui_section == self.HOOKS_SECTION)
263 query = self._filter_by_repo(RepoRhodeCodeUi, query)
272 query = self._filter_by_repo(RepoRhodeCodeUi, query)
264 return query.all()
273 return query.all()
265
274
266 def _get_settings_query(self):
275 def _get_settings_query(self):
267 q = self.SettingsDbModel.query()
276 q = self.SettingsDbModel.query()
268 return self._filter_by_repo(RepoRhodeCodeSetting, q)
277 return self._filter_by_repo(RepoRhodeCodeSetting, q)
269
278
270 def list_enabled_social_plugins(self, settings):
279 def list_enabled_social_plugins(self, settings):
271 enabled = []
280 enabled = []
272 for plug in SOCIAL_PLUGINS_LIST:
281 for plug in SOCIAL_PLUGINS_LIST:
273 if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug)
282 if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug)
274 )):
283 )):
275 enabled.append(plug)
284 enabled.append(plug)
276 return enabled
285 return enabled
277
286
278
287
279 def assert_repo_settings(func):
288 def assert_repo_settings(func):
280 @wraps(func)
289 @wraps(func)
281 def _wrapper(self, *args, **kwargs):
290 def _wrapper(self, *args, **kwargs):
282 if not self.repo_settings:
291 if not self.repo_settings:
283 raise Exception('Repository is not specified')
292 raise Exception('Repository is not specified')
284 return func(self, *args, **kwargs)
293 return func(self, *args, **kwargs)
285 return _wrapper
294 return _wrapper
286
295
287
296
288 class IssueTrackerSettingsModel(object):
297 class IssueTrackerSettingsModel(object):
289 INHERIT_SETTINGS = 'inherit_issue_tracker_settings'
298 INHERIT_SETTINGS = 'inherit_issue_tracker_settings'
290 SETTINGS_PREFIX = 'issuetracker_'
299 SETTINGS_PREFIX = 'issuetracker_'
291
300
292 def __init__(self, sa=None, repo=None):
301 def __init__(self, sa=None, repo=None):
293 self.global_settings = SettingsModel(sa=sa)
302 self.global_settings = SettingsModel(sa=sa)
294 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
303 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
295
304
296 @property
305 @property
297 def inherit_global_settings(self):
306 def inherit_global_settings(self):
298 if not self.repo_settings:
307 if not self.repo_settings:
299 return True
308 return True
300 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
309 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
301 return setting.app_settings_value if setting else True
310 return setting.app_settings_value if setting else True
302
311
303 @inherit_global_settings.setter
312 @inherit_global_settings.setter
304 def inherit_global_settings(self, value):
313 def inherit_global_settings(self, value):
305 if self.repo_settings:
314 if self.repo_settings:
306 settings = self.repo_settings.create_or_update_setting(
315 settings = self.repo_settings.create_or_update_setting(
307 self.INHERIT_SETTINGS, value, type_='bool')
316 self.INHERIT_SETTINGS, value, type_='bool')
308 Session().add(settings)
317 Session().add(settings)
309
318
310 def _get_keyname(self, key, uid, prefix=''):
319 def _get_keyname(self, key, uid, prefix=''):
311 return '{0}{1}{2}_{3}'.format(
320 return '{0}{1}{2}_{3}'.format(
312 prefix, self.SETTINGS_PREFIX, key, uid)
321 prefix, self.SETTINGS_PREFIX, key, uid)
313
322
314 def _make_dict_for_settings(self, qs):
323 def _make_dict_for_settings(self, qs):
315 prefix_match = self._get_keyname('pat', '', 'rhodecode_')
324 prefix_match = self._get_keyname('pat', '', 'rhodecode_')
316
325
317 issuetracker_entries = {}
326 issuetracker_entries = {}
318 # create keys
327 # create keys
319 for k, v in qs.items():
328 for k, v in qs.items():
320 if k.startswith(prefix_match):
329 if k.startswith(prefix_match):
321 uid = k[len(prefix_match):]
330 uid = k[len(prefix_match):]
322 issuetracker_entries[uid] = None
331 issuetracker_entries[uid] = None
323
332
324 # populate
333 # populate
325 for uid in issuetracker_entries:
334 for uid in issuetracker_entries:
326 issuetracker_entries[uid] = AttributeDict({
335 issuetracker_entries[uid] = AttributeDict({
327 'pat': qs.get(self._get_keyname('pat', uid, 'rhodecode_')),
336 'pat': qs.get(self._get_keyname('pat', uid, 'rhodecode_')),
328 'url': qs.get(self._get_keyname('url', uid, 'rhodecode_')),
337 'url': qs.get(self._get_keyname('url', uid, 'rhodecode_')),
329 'pref': qs.get(self._get_keyname('pref', uid, 'rhodecode_')),
338 'pref': qs.get(self._get_keyname('pref', uid, 'rhodecode_')),
330 'desc': qs.get(self._get_keyname('desc', uid, 'rhodecode_')),
339 'desc': qs.get(self._get_keyname('desc', uid, 'rhodecode_')),
331 })
340 })
332 return issuetracker_entries
341 return issuetracker_entries
333
342
334 def get_global_settings(self, cache=False):
343 def get_global_settings(self, cache=False):
335 """
344 """
336 Returns list of global issue tracker settings
345 Returns list of global issue tracker settings
337 """
346 """
338 defaults = self.global_settings.get_all_settings(cache=cache)
347 defaults = self.global_settings.get_all_settings(cache=cache)
339 settings = self._make_dict_for_settings(defaults)
348 settings = self._make_dict_for_settings(defaults)
340 return settings
349 return settings
341
350
342 def get_repo_settings(self, cache=False):
351 def get_repo_settings(self, cache=False):
343 """
352 """
344 Returns list of issue tracker settings per repository
353 Returns list of issue tracker settings per repository
345 """
354 """
346 if not self.repo_settings:
355 if not self.repo_settings:
347 raise Exception('Repository is not specified')
356 raise Exception('Repository is not specified')
348 all_settings = self.repo_settings.get_all_settings(cache=cache)
357 all_settings = self.repo_settings.get_all_settings(cache=cache)
349 settings = self._make_dict_for_settings(all_settings)
358 settings = self._make_dict_for_settings(all_settings)
350 return settings
359 return settings
351
360
352 def get_settings(self, cache=False):
361 def get_settings(self, cache=False):
353 if self.inherit_global_settings:
362 if self.inherit_global_settings:
354 return self.get_global_settings(cache=cache)
363 return self.get_global_settings(cache=cache)
355 else:
364 else:
356 return self.get_repo_settings(cache=cache)
365 return self.get_repo_settings(cache=cache)
357
366
358 def delete_entries(self, uid):
367 def delete_entries(self, uid):
359 if self.repo_settings:
368 if self.repo_settings:
360 all_patterns = self.get_repo_settings()
369 all_patterns = self.get_repo_settings()
361 settings_model = self.repo_settings
370 settings_model = self.repo_settings
362 else:
371 else:
363 all_patterns = self.get_global_settings()
372 all_patterns = self.get_global_settings()
364 settings_model = self.global_settings
373 settings_model = self.global_settings
365 entries = all_patterns.get(uid)
374 entries = all_patterns.get(uid)
366
375
367 for del_key in entries:
376 for del_key in entries:
368 setting_name = self._get_keyname(del_key, uid)
377 setting_name = self._get_keyname(del_key, uid)
369 entry = settings_model.get_setting_by_name(setting_name)
378 entry = settings_model.get_setting_by_name(setting_name)
370 if entry:
379 if entry:
371 Session().delete(entry)
380 Session().delete(entry)
372
381
373 Session().commit()
382 Session().commit()
374
383
375 def create_or_update_setting(
384 def create_or_update_setting(
376 self, name, val=Optional(''), type_=Optional('unicode')):
385 self, name, val=Optional(''), type_=Optional('unicode')):
377 if self.repo_settings:
386 if self.repo_settings:
378 setting = self.repo_settings.create_or_update_setting(
387 setting = self.repo_settings.create_or_update_setting(
379 name, val, type_)
388 name, val, type_)
380 else:
389 else:
381 setting = self.global_settings.create_or_update_setting(
390 setting = self.global_settings.create_or_update_setting(
382 name, val, type_)
391 name, val, type_)
383 return setting
392 return setting
384
393
385
394
386 class VcsSettingsModel(object):
395 class VcsSettingsModel(object):
387
396
388 INHERIT_SETTINGS = 'inherit_vcs_settings'
397 INHERIT_SETTINGS = 'inherit_vcs_settings'
389 GENERAL_SETTINGS = ('use_outdated_comments', 'pr_merge_enabled')
398 GENERAL_SETTINGS = ('use_outdated_comments', 'pr_merge_enabled')
390 HOOKS_SETTINGS = (
399 HOOKS_SETTINGS = (
391 ('hooks', 'changegroup.repo_size'),
400 ('hooks', 'changegroup.repo_size'),
392 ('hooks', 'changegroup.push_logger'),
401 ('hooks', 'changegroup.push_logger'),
393 ('hooks', 'outgoing.pull_logger'))
402 ('hooks', 'outgoing.pull_logger'))
394 HG_SETTINGS = (
403 HG_SETTINGS = (
395 ('extensions', 'largefiles'), ('phases', 'publish'))
404 ('extensions', 'largefiles'), ('phases', 'publish'))
396 GLOBAL_HG_SETTINGS = HG_SETTINGS + (('extensions', 'hgsubversion'), )
405 GLOBAL_HG_SETTINGS = HG_SETTINGS + (('extensions', 'hgsubversion'), )
397 SVN_BRANCH_SECTION = 'vcs_svn_branch'
406 SVN_BRANCH_SECTION = 'vcs_svn_branch'
398 SVN_TAG_SECTION = 'vcs_svn_tag'
407 SVN_TAG_SECTION = 'vcs_svn_tag'
399 SSL_SETTING = ('web', 'push_ssl')
408 SSL_SETTING = ('web', 'push_ssl')
400 PATH_SETTING = ('paths', '/')
409 PATH_SETTING = ('paths', '/')
401
410
402 def __init__(self, sa=None, repo=None):
411 def __init__(self, sa=None, repo=None):
403 self.global_settings = SettingsModel(sa=sa)
412 self.global_settings = SettingsModel(sa=sa)
404 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
413 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
405 self._ui_settings = self.HG_SETTINGS + self.HOOKS_SETTINGS
414 self._ui_settings = self.HG_SETTINGS + self.HOOKS_SETTINGS
406 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
415 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
407
416
408 @property
417 @property
409 @assert_repo_settings
418 @assert_repo_settings
410 def inherit_global_settings(self):
419 def inherit_global_settings(self):
411 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
420 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
412 return setting.app_settings_value if setting else True
421 return setting.app_settings_value if setting else True
413
422
414 @inherit_global_settings.setter
423 @inherit_global_settings.setter
415 @assert_repo_settings
424 @assert_repo_settings
416 def inherit_global_settings(self, value):
425 def inherit_global_settings(self, value):
417 self.repo_settings.create_or_update_setting(
426 self.repo_settings.create_or_update_setting(
418 self.INHERIT_SETTINGS, value, type_='bool')
427 self.INHERIT_SETTINGS, value, type_='bool')
419
428
420 def get_global_svn_branch_patterns(self):
429 def get_global_svn_branch_patterns(self):
421 return self.global_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
430 return self.global_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
422
431
423 @assert_repo_settings
432 @assert_repo_settings
424 def get_repo_svn_branch_patterns(self):
433 def get_repo_svn_branch_patterns(self):
425 return self.repo_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
434 return self.repo_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
426
435
427 def get_global_svn_tag_patterns(self):
436 def get_global_svn_tag_patterns(self):
428 return self.global_settings.get_ui_by_section(self.SVN_TAG_SECTION)
437 return self.global_settings.get_ui_by_section(self.SVN_TAG_SECTION)
429
438
430 @assert_repo_settings
439 @assert_repo_settings
431 def get_repo_svn_tag_patterns(self):
440 def get_repo_svn_tag_patterns(self):
432 return self.repo_settings.get_ui_by_section(self.SVN_TAG_SECTION)
441 return self.repo_settings.get_ui_by_section(self.SVN_TAG_SECTION)
433
442
434 def get_global_settings(self):
443 def get_global_settings(self):
435 return self._collect_all_settings(global_=True)
444 return self._collect_all_settings(global_=True)
436
445
437 @assert_repo_settings
446 @assert_repo_settings
438 def get_repo_settings(self):
447 def get_repo_settings(self):
439 return self._collect_all_settings(global_=False)
448 return self._collect_all_settings(global_=False)
440
449
441 @assert_repo_settings
450 @assert_repo_settings
442 def create_or_update_repo_settings(
451 def create_or_update_repo_settings(
443 self, data, inherit_global_settings=False):
452 self, data, inherit_global_settings=False):
444 from rhodecode.model.scm import ScmModel
453 from rhodecode.model.scm import ScmModel
445
454
446 self.inherit_global_settings = inherit_global_settings
455 self.inherit_global_settings = inherit_global_settings
447
456
448 repo = self.repo_settings.get_repo()
457 repo = self.repo_settings.get_repo()
449 if not inherit_global_settings:
458 if not inherit_global_settings:
450 if repo.repo_type == 'svn':
459 if repo.repo_type == 'svn':
451 self.create_repo_svn_settings(data)
460 self.create_repo_svn_settings(data)
452 else:
461 else:
453 self.create_or_update_repo_hook_settings(data)
462 self.create_or_update_repo_hook_settings(data)
454 self.create_or_update_repo_pr_settings(data)
463 self.create_or_update_repo_pr_settings(data)
455
464
456 if repo.repo_type == 'hg':
465 if repo.repo_type == 'hg':
457 self.create_or_update_repo_hg_settings(data)
466 self.create_or_update_repo_hg_settings(data)
458
467
459 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
468 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
460
469
461 @assert_repo_settings
470 @assert_repo_settings
462 def create_or_update_repo_hook_settings(self, data):
471 def create_or_update_repo_hook_settings(self, data):
463 for section, key in self.HOOKS_SETTINGS:
472 for section, key in self.HOOKS_SETTINGS:
464 data_key = self._get_form_ui_key(section, key)
473 data_key = self._get_form_ui_key(section, key)
465 if data_key not in data:
474 if data_key not in data:
466 raise ValueError(
475 raise ValueError(
467 'The given data does not contain {} key'.format(data_key))
476 'The given data does not contain {} key'.format(data_key))
468
477
469 active = data.get(data_key)
478 active = data.get(data_key)
470 repo_setting = self.repo_settings.get_ui_by_section_and_key(
479 repo_setting = self.repo_settings.get_ui_by_section_and_key(
471 section, key)
480 section, key)
472 if not repo_setting:
481 if not repo_setting:
473 global_setting = self.global_settings.\
482 global_setting = self.global_settings.\
474 get_ui_by_section_and_key(section, key)
483 get_ui_by_section_and_key(section, key)
475 self.repo_settings.create_ui_section_value(
484 self.repo_settings.create_ui_section_value(
476 section, global_setting.ui_value, key=key, active=active)
485 section, global_setting.ui_value, key=key, active=active)
477 else:
486 else:
478 repo_setting.ui_active = active
487 repo_setting.ui_active = active
479 Session().add(repo_setting)
488 Session().add(repo_setting)
480
489
481 def update_global_hook_settings(self, data):
490 def update_global_hook_settings(self, data):
482 for section, key in self.HOOKS_SETTINGS:
491 for section, key in self.HOOKS_SETTINGS:
483 data_key = self._get_form_ui_key(section, key)
492 data_key = self._get_form_ui_key(section, key)
484 if data_key not in data:
493 if data_key not in data:
485 raise ValueError(
494 raise ValueError(
486 'The given data does not contain {} key'.format(data_key))
495 'The given data does not contain {} key'.format(data_key))
487 active = data.get(data_key)
496 active = data.get(data_key)
488 repo_setting = self.global_settings.get_ui_by_section_and_key(
497 repo_setting = self.global_settings.get_ui_by_section_and_key(
489 section, key)
498 section, key)
490 repo_setting.ui_active = active
499 repo_setting.ui_active = active
491 Session().add(repo_setting)
500 Session().add(repo_setting)
492
501
493 @assert_repo_settings
502 @assert_repo_settings
494 def create_or_update_repo_pr_settings(self, data):
503 def create_or_update_repo_pr_settings(self, data):
495 return self._create_or_update_general_settings(
504 return self._create_or_update_general_settings(
496 self.repo_settings, data)
505 self.repo_settings, data)
497
506
498 def create_or_update_global_pr_settings(self, data):
507 def create_or_update_global_pr_settings(self, data):
499 return self._create_or_update_general_settings(
508 return self._create_or_update_general_settings(
500 self.global_settings, data)
509 self.global_settings, data)
501
510
502 @assert_repo_settings
511 @assert_repo_settings
503 def create_repo_svn_settings(self, data):
512 def create_repo_svn_settings(self, data):
504 return self._create_svn_settings(self.repo_settings, data)
513 return self._create_svn_settings(self.repo_settings, data)
505
514
506 def create_global_svn_settings(self, data):
515 def create_global_svn_settings(self, data):
507 return self._create_svn_settings(self.global_settings, data)
516 return self._create_svn_settings(self.global_settings, data)
508
517
509 @assert_repo_settings
518 @assert_repo_settings
510 def create_or_update_repo_hg_settings(self, data):
519 def create_or_update_repo_hg_settings(self, data):
511 largefiles, phases = self.HG_SETTINGS
520 largefiles, phases = self.HG_SETTINGS
512 largefiles_key, phases_key = self._get_hg_settings(
521 largefiles_key, phases_key = self._get_hg_settings(
513 self.HG_SETTINGS, data)
522 self.HG_SETTINGS, data)
514 self._create_or_update_ui(
523 self._create_or_update_ui(
515 self.repo_settings, *largefiles, value='',
524 self.repo_settings, *largefiles, value='',
516 active=data[largefiles_key])
525 active=data[largefiles_key])
517 self._create_or_update_ui(
526 self._create_or_update_ui(
518 self.repo_settings, *phases, value=safe_str(data[phases_key]))
527 self.repo_settings, *phases, value=safe_str(data[phases_key]))
519
528
520 def create_or_update_global_hg_settings(self, data):
529 def create_or_update_global_hg_settings(self, data):
521 largefiles, phases, subversion = self.GLOBAL_HG_SETTINGS
530 largefiles, phases, subversion = self.GLOBAL_HG_SETTINGS
522 largefiles_key, phases_key, subversion_key = self._get_hg_settings(
531 largefiles_key, phases_key, subversion_key = self._get_hg_settings(
523 self.GLOBAL_HG_SETTINGS, data)
532 self.GLOBAL_HG_SETTINGS, data)
524 self._create_or_update_ui(
533 self._create_or_update_ui(
525 self.global_settings, *largefiles, value='',
534 self.global_settings, *largefiles, value='',
526 active=data[largefiles_key])
535 active=data[largefiles_key])
527 self._create_or_update_ui(
536 self._create_or_update_ui(
528 self.global_settings, *phases, value=safe_str(data[phases_key]))
537 self.global_settings, *phases, value=safe_str(data[phases_key]))
529 self._create_or_update_ui(
538 self._create_or_update_ui(
530 self.global_settings, *subversion, active=data[subversion_key])
539 self.global_settings, *subversion, active=data[subversion_key])
531
540
532 def update_global_ssl_setting(self, value):
541 def update_global_ssl_setting(self, value):
533 self._create_or_update_ui(
542 self._create_or_update_ui(
534 self.global_settings, *self.SSL_SETTING, value=value)
543 self.global_settings, *self.SSL_SETTING, value=value)
535
544
536 def update_global_path_setting(self, value):
545 def update_global_path_setting(self, value):
537 self._create_or_update_ui(
546 self._create_or_update_ui(
538 self.global_settings, *self.PATH_SETTING, value=value)
547 self.global_settings, *self.PATH_SETTING, value=value)
539
548
540 @assert_repo_settings
549 @assert_repo_settings
541 def delete_repo_svn_pattern(self, id_):
550 def delete_repo_svn_pattern(self, id_):
542 self.repo_settings.delete_ui(id_)
551 self.repo_settings.delete_ui(id_)
543
552
544 def delete_global_svn_pattern(self, id_):
553 def delete_global_svn_pattern(self, id_):
545 self.global_settings.delete_ui(id_)
554 self.global_settings.delete_ui(id_)
546
555
547 @assert_repo_settings
556 @assert_repo_settings
548 def get_repo_ui_settings(self, section=None, key=None):
557 def get_repo_ui_settings(self, section=None, key=None):
549 global_uis = self.global_settings.get_ui(section, key)
558 global_uis = self.global_settings.get_ui(section, key)
550 repo_uis = self.repo_settings.get_ui(section, key)
559 repo_uis = self.repo_settings.get_ui(section, key)
551 filtered_repo_uis = self._filter_ui_settings(repo_uis)
560 filtered_repo_uis = self._filter_ui_settings(repo_uis)
552 filtered_repo_uis_keys = [
561 filtered_repo_uis_keys = [
553 (s.section, s.key) for s in filtered_repo_uis]
562 (s.section, s.key) for s in filtered_repo_uis]
554
563
555 def _is_global_ui_filtered(ui):
564 def _is_global_ui_filtered(ui):
556 return (
565 return (
557 (ui.section, ui.key) in filtered_repo_uis_keys
566 (ui.section, ui.key) in filtered_repo_uis_keys
558 or ui.section in self._svn_sections)
567 or ui.section in self._svn_sections)
559
568
560 filtered_global_uis = [
569 filtered_global_uis = [
561 ui for ui in global_uis if not _is_global_ui_filtered(ui)]
570 ui for ui in global_uis if not _is_global_ui_filtered(ui)]
562
571
563 return filtered_global_uis + filtered_repo_uis
572 return filtered_global_uis + filtered_repo_uis
564
573
565 def get_global_ui_settings(self, section=None, key=None):
574 def get_global_ui_settings(self, section=None, key=None):
566 return self.global_settings.get_ui(section, key)
575 return self.global_settings.get_ui(section, key)
567
576
568 def get_ui_settings(self, section=None, key=None):
577 def get_ui_settings(self, section=None, key=None):
569 if not self.repo_settings or self.inherit_global_settings:
578 if not self.repo_settings or self.inherit_global_settings:
570 return self.get_global_ui_settings(section, key)
579 return self.get_global_ui_settings(section, key)
571 else:
580 else:
572 return self.get_repo_ui_settings(section, key)
581 return self.get_repo_ui_settings(section, key)
573
582
574 def get_svn_patterns(self, section=None):
583 def get_svn_patterns(self, section=None):
575 if not self.repo_settings:
584 if not self.repo_settings:
576 return self.get_global_ui_settings(section)
585 return self.get_global_ui_settings(section)
577 else:
586 else:
578 return self.get_repo_ui_settings(section)
587 return self.get_repo_ui_settings(section)
579
588
580 @assert_repo_settings
589 @assert_repo_settings
581 def get_repo_general_settings(self):
590 def get_repo_general_settings(self):
582 global_settings = self.global_settings.get_all_settings()
591 global_settings = self.global_settings.get_all_settings()
583 repo_settings = self.repo_settings.get_all_settings()
592 repo_settings = self.repo_settings.get_all_settings()
584 filtered_repo_settings = self._filter_general_settings(repo_settings)
593 filtered_repo_settings = self._filter_general_settings(repo_settings)
585 global_settings.update(filtered_repo_settings)
594 global_settings.update(filtered_repo_settings)
586 return global_settings
595 return global_settings
587
596
588 def get_global_general_settings(self):
597 def get_global_general_settings(self):
589 return self.global_settings.get_all_settings()
598 return self.global_settings.get_all_settings()
590
599
591 def get_general_settings(self):
600 def get_general_settings(self):
592 if not self.repo_settings or self.inherit_global_settings:
601 if not self.repo_settings or self.inherit_global_settings:
593 return self.get_global_general_settings()
602 return self.get_global_general_settings()
594 else:
603 else:
595 return self.get_repo_general_settings()
604 return self.get_repo_general_settings()
596
605
597 def get_repos_location(self):
606 def get_repos_location(self):
598 return self.global_settings.get_ui_by_key('/').ui_value
607 return self.global_settings.get_ui_by_key('/').ui_value
599
608
600 def _filter_ui_settings(self, settings):
609 def _filter_ui_settings(self, settings):
601 filtered_settings = [
610 filtered_settings = [
602 s for s in settings if self._should_keep_setting(s)]
611 s for s in settings if self._should_keep_setting(s)]
603 return filtered_settings
612 return filtered_settings
604
613
605 def _should_keep_setting(self, setting):
614 def _should_keep_setting(self, setting):
606 keep = (
615 keep = (
607 (setting.section, setting.key) in self._ui_settings or
616 (setting.section, setting.key) in self._ui_settings or
608 setting.section in self._svn_sections)
617 setting.section in self._svn_sections)
609 return keep
618 return keep
610
619
611 def _filter_general_settings(self, settings):
620 def _filter_general_settings(self, settings):
612 keys = ['rhodecode_{}'.format(key) for key in self.GENERAL_SETTINGS]
621 keys = ['rhodecode_{}'.format(key) for key in self.GENERAL_SETTINGS]
613 return {
622 return {
614 k: settings[k]
623 k: settings[k]
615 for k in settings if k in keys}
624 for k in settings if k in keys}
616
625
617 def _collect_all_settings(self, global_=False):
626 def _collect_all_settings(self, global_=False):
618 settings = self.global_settings if global_ else self.repo_settings
627 settings = self.global_settings if global_ else self.repo_settings
619 result = {}
628 result = {}
620
629
621 for section, key in self._ui_settings:
630 for section, key in self._ui_settings:
622 ui = settings.get_ui_by_section_and_key(section, key)
631 ui = settings.get_ui_by_section_and_key(section, key)
623 result_key = self._get_form_ui_key(section, key)
632 result_key = self._get_form_ui_key(section, key)
624 if ui:
633 if ui:
625 if section in ('hooks', 'extensions'):
634 if section in ('hooks', 'extensions'):
626 result[result_key] = ui.ui_active
635 result[result_key] = ui.ui_active
627 else:
636 else:
628 result[result_key] = ui.ui_value
637 result[result_key] = ui.ui_value
629
638
630 for name in self.GENERAL_SETTINGS:
639 for name in self.GENERAL_SETTINGS:
631 setting = settings.get_setting_by_name(name)
640 setting = settings.get_setting_by_name(name)
632 if setting:
641 if setting:
633 result_key = 'rhodecode_{}'.format(name)
642 result_key = 'rhodecode_{}'.format(name)
634 result[result_key] = setting.app_settings_value
643 result[result_key] = setting.app_settings_value
635
644
636 return result
645 return result
637
646
638 def _get_form_ui_key(self, section, key):
647 def _get_form_ui_key(self, section, key):
639 return '{section}_{key}'.format(
648 return '{section}_{key}'.format(
640 section=section, key=key.replace('.', '_'))
649 section=section, key=key.replace('.', '_'))
641
650
642 def _create_or_update_ui(
651 def _create_or_update_ui(
643 self, settings, section, key, value=None, active=None):
652 self, settings, section, key, value=None, active=None):
644 ui = settings.get_ui_by_section_and_key(section, key)
653 ui = settings.get_ui_by_section_and_key(section, key)
645 if not ui:
654 if not ui:
646 active = True if active is None else active
655 active = True if active is None else active
647 settings.create_ui_section_value(
656 settings.create_ui_section_value(
648 section, value, key=key, active=active)
657 section, value, key=key, active=active)
649 else:
658 else:
650 if active is not None:
659 if active is not None:
651 ui.ui_active = active
660 ui.ui_active = active
652 if value is not None:
661 if value is not None:
653 ui.ui_value = value
662 ui.ui_value = value
654 Session().add(ui)
663 Session().add(ui)
655
664
656 def _create_svn_settings(self, settings, data):
665 def _create_svn_settings(self, settings, data):
657 svn_settings = {
666 svn_settings = {
658 'new_svn_branch': self.SVN_BRANCH_SECTION,
667 'new_svn_branch': self.SVN_BRANCH_SECTION,
659 'new_svn_tag': self.SVN_TAG_SECTION
668 'new_svn_tag': self.SVN_TAG_SECTION
660 }
669 }
661 for key in svn_settings:
670 for key in svn_settings:
662 if data.get(key):
671 if data.get(key):
663 settings.create_ui_section_value(svn_settings[key], data[key])
672 settings.create_ui_section_value(svn_settings[key], data[key])
664
673
665 def _create_or_update_general_settings(self, settings, data):
674 def _create_or_update_general_settings(self, settings, data):
666 for name in self.GENERAL_SETTINGS:
675 for name in self.GENERAL_SETTINGS:
667 data_key = 'rhodecode_{}'.format(name)
676 data_key = 'rhodecode_{}'.format(name)
668 if data_key not in data:
677 if data_key not in data:
669 raise ValueError(
678 raise ValueError(
670 'The given data does not contain {} key'.format(data_key))
679 'The given data does not contain {} key'.format(data_key))
671 setting = settings.create_or_update_setting(
680 setting = settings.create_or_update_setting(
672 name, data[data_key], 'bool')
681 name, data[data_key], 'bool')
673 Session().add(setting)
682 Session().add(setting)
674
683
675 def _get_hg_settings(self, settings, data):
684 def _get_hg_settings(self, settings, data):
676 data_keys = [self._get_form_ui_key(*s) for s in settings]
685 data_keys = [self._get_form_ui_key(*s) for s in settings]
677 for data_key in data_keys:
686 for data_key in data_keys:
678 if data_key not in data:
687 if data_key not in data:
679 raise ValueError(
688 raise ValueError(
680 'The given data does not contain {} key'.format(data_key))
689 'The given data does not contain {} key'.format(data_key))
681 return data_keys
690 return data_keys
General Comments 0
You need to be logged in to leave comments. Login now