##// END OF EJS Templates
caches: use process aware settings cache with proper invalidation.
marcink -
r2937:23a83d11 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,829 +1,839 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2018 RhodeCode GmbH
3 # Copyright (C) 2010-2018 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 os
21 import os
22 import hashlib
22 import hashlib
23 import logging
23 import logging
24 import time
25 from collections import namedtuple
24 from collections import namedtuple
26 from functools import wraps
25 from functools import wraps
27 import bleach
26 import bleach
28
27
29 from rhodecode.lib import rc_cache
28 from rhodecode.lib import rc_cache
30 from rhodecode.lib.utils2 import (
29 from rhodecode.lib.utils2 import (
31 Optional, AttributeDict, safe_str, remove_prefix, str2bool)
30 Optional, AttributeDict, safe_str, remove_prefix, str2bool)
32 from rhodecode.lib.vcs.backends import base
31 from rhodecode.lib.vcs.backends import base
33 from rhodecode.model import BaseModel
32 from rhodecode.model import BaseModel
34 from rhodecode.model.db import (
33 from rhodecode.model.db import (
35 RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi, RhodeCodeSetting)
34 RepoRhodeCodeUi, RepoRhodeCodeSetting, RhodeCodeUi, RhodeCodeSetting, CacheKey)
36 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
37
36
38
37
39 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
40
39
41
40
42 UiSetting = namedtuple(
41 UiSetting = namedtuple(
43 'UiSetting', ['section', 'key', 'value', 'active'])
42 'UiSetting', ['section', 'key', 'value', 'active'])
44
43
45 SOCIAL_PLUGINS_LIST = ['github', 'bitbucket', 'twitter', 'google']
44 SOCIAL_PLUGINS_LIST = ['github', 'bitbucket', 'twitter', 'google']
46
45
47
46
48 class SettingNotFound(Exception):
47 class SettingNotFound(Exception):
49 def __init__(self, setting_id):
48 def __init__(self, setting_id):
50 msg = 'Setting `{}` is not found'.format(setting_id)
49 msg = 'Setting `{}` is not found'.format(setting_id)
51 super(SettingNotFound, self).__init__(msg)
50 super(SettingNotFound, self).__init__(msg)
52
51
53
52
54 class SettingsModel(BaseModel):
53 class SettingsModel(BaseModel):
55 BUILTIN_HOOKS = (
54 BUILTIN_HOOKS = (
56 RhodeCodeUi.HOOK_REPO_SIZE, RhodeCodeUi.HOOK_PUSH,
55 RhodeCodeUi.HOOK_REPO_SIZE, RhodeCodeUi.HOOK_PUSH,
57 RhodeCodeUi.HOOK_PRE_PUSH, RhodeCodeUi.HOOK_PRETX_PUSH,
56 RhodeCodeUi.HOOK_PRE_PUSH, RhodeCodeUi.HOOK_PRETX_PUSH,
58 RhodeCodeUi.HOOK_PULL, RhodeCodeUi.HOOK_PRE_PULL,
57 RhodeCodeUi.HOOK_PULL, RhodeCodeUi.HOOK_PRE_PULL,
59 RhodeCodeUi.HOOK_PUSH_KEY,)
58 RhodeCodeUi.HOOK_PUSH_KEY,)
60 HOOKS_SECTION = 'hooks'
59 HOOKS_SECTION = 'hooks'
61
60
62 def __init__(self, sa=None, repo=None):
61 def __init__(self, sa=None, repo=None):
63 self.repo = repo
62 self.repo = repo
64 self.UiDbModel = RepoRhodeCodeUi if repo else RhodeCodeUi
63 self.UiDbModel = RepoRhodeCodeUi if repo else RhodeCodeUi
65 self.SettingsDbModel = (
64 self.SettingsDbModel = (
66 RepoRhodeCodeSetting if repo else RhodeCodeSetting)
65 RepoRhodeCodeSetting if repo else RhodeCodeSetting)
67 super(SettingsModel, self).__init__(sa)
66 super(SettingsModel, self).__init__(sa)
68
67
69 def get_ui_by_key(self, key):
68 def get_ui_by_key(self, key):
70 q = self.UiDbModel.query()
69 q = self.UiDbModel.query()
71 q = q.filter(self.UiDbModel.ui_key == key)
70 q = q.filter(self.UiDbModel.ui_key == key)
72 q = self._filter_by_repo(RepoRhodeCodeUi, q)
71 q = self._filter_by_repo(RepoRhodeCodeUi, q)
73 return q.scalar()
72 return q.scalar()
74
73
75 def get_ui_by_section(self, section):
74 def get_ui_by_section(self, section):
76 q = self.UiDbModel.query()
75 q = self.UiDbModel.query()
77 q = q.filter(self.UiDbModel.ui_section == section)
76 q = q.filter(self.UiDbModel.ui_section == section)
78 q = self._filter_by_repo(RepoRhodeCodeUi, q)
77 q = self._filter_by_repo(RepoRhodeCodeUi, q)
79 return q.all()
78 return q.all()
80
79
81 def get_ui_by_section_and_key(self, section, key):
80 def get_ui_by_section_and_key(self, section, key):
82 q = self.UiDbModel.query()
81 q = self.UiDbModel.query()
83 q = q.filter(self.UiDbModel.ui_section == section)
82 q = q.filter(self.UiDbModel.ui_section == section)
84 q = q.filter(self.UiDbModel.ui_key == key)
83 q = q.filter(self.UiDbModel.ui_key == key)
85 q = self._filter_by_repo(RepoRhodeCodeUi, q)
84 q = self._filter_by_repo(RepoRhodeCodeUi, q)
86 return q.scalar()
85 return q.scalar()
87
86
88 def get_ui(self, section=None, key=None):
87 def get_ui(self, section=None, key=None):
89 q = self.UiDbModel.query()
88 q = self.UiDbModel.query()
90 q = self._filter_by_repo(RepoRhodeCodeUi, q)
89 q = self._filter_by_repo(RepoRhodeCodeUi, q)
91
90
92 if section:
91 if section:
93 q = q.filter(self.UiDbModel.ui_section == section)
92 q = q.filter(self.UiDbModel.ui_section == section)
94 if key:
93 if key:
95 q = q.filter(self.UiDbModel.ui_key == key)
94 q = q.filter(self.UiDbModel.ui_key == key)
96
95
97 # TODO: mikhail: add caching
96 # TODO: mikhail: add caching
98 result = [
97 result = [
99 UiSetting(
98 UiSetting(
100 section=safe_str(r.ui_section), key=safe_str(r.ui_key),
99 section=safe_str(r.ui_section), key=safe_str(r.ui_key),
101 value=safe_str(r.ui_value), active=r.ui_active
100 value=safe_str(r.ui_value), active=r.ui_active
102 )
101 )
103 for r in q.all()
102 for r in q.all()
104 ]
103 ]
105 return result
104 return result
106
105
107 def get_builtin_hooks(self):
106 def get_builtin_hooks(self):
108 q = self.UiDbModel.query()
107 q = self.UiDbModel.query()
109 q = q.filter(self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
108 q = q.filter(self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
110 return self._get_hooks(q)
109 return self._get_hooks(q)
111
110
112 def get_custom_hooks(self):
111 def get_custom_hooks(self):
113 q = self.UiDbModel.query()
112 q = self.UiDbModel.query()
114 q = q.filter(~self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
113 q = q.filter(~self.UiDbModel.ui_key.in_(self.BUILTIN_HOOKS))
115 return self._get_hooks(q)
114 return self._get_hooks(q)
116
115
117 def create_ui_section_value(self, section, val, key=None, active=True):
116 def create_ui_section_value(self, section, val, key=None, active=True):
118 new_ui = self.UiDbModel()
117 new_ui = self.UiDbModel()
119 new_ui.ui_section = section
118 new_ui.ui_section = section
120 new_ui.ui_value = val
119 new_ui.ui_value = val
121 new_ui.ui_active = active
120 new_ui.ui_active = active
122
121
123 if self.repo:
122 if self.repo:
124 repo = self._get_repo(self.repo)
123 repo = self._get_repo(self.repo)
125 repository_id = repo.repo_id
124 repository_id = repo.repo_id
126 new_ui.repository_id = repository_id
125 new_ui.repository_id = repository_id
127
126
128 if not key:
127 if not key:
129 # keys are unique so they need appended info
128 # keys are unique so they need appended info
130 if self.repo:
129 if self.repo:
131 key = hashlib.sha1(
130 key = hashlib.sha1(
132 '{}{}{}'.format(section, val, repository_id)).hexdigest()
131 '{}{}{}'.format(section, val, repository_id)).hexdigest()
133 else:
132 else:
134 key = hashlib.sha1('{}{}'.format(section, val)).hexdigest()
133 key = hashlib.sha1('{}{}'.format(section, val)).hexdigest()
135
134
136 new_ui.ui_key = key
135 new_ui.ui_key = key
137
136
138 Session().add(new_ui)
137 Session().add(new_ui)
139 return new_ui
138 return new_ui
140
139
141 def create_or_update_hook(self, key, value):
140 def create_or_update_hook(self, key, value):
142 ui = (
141 ui = (
143 self.get_ui_by_section_and_key(self.HOOKS_SECTION, key) or
142 self.get_ui_by_section_and_key(self.HOOKS_SECTION, key) or
144 self.UiDbModel())
143 self.UiDbModel())
145 ui.ui_section = self.HOOKS_SECTION
144 ui.ui_section = self.HOOKS_SECTION
146 ui.ui_active = True
145 ui.ui_active = True
147 ui.ui_key = key
146 ui.ui_key = key
148 ui.ui_value = value
147 ui.ui_value = value
149
148
150 if self.repo:
149 if self.repo:
151 repo = self._get_repo(self.repo)
150 repo = self._get_repo(self.repo)
152 repository_id = repo.repo_id
151 repository_id = repo.repo_id
153 ui.repository_id = repository_id
152 ui.repository_id = repository_id
154
153
155 Session().add(ui)
154 Session().add(ui)
156 return ui
155 return ui
157
156
158 def delete_ui(self, id_):
157 def delete_ui(self, id_):
159 ui = self.UiDbModel.get(id_)
158 ui = self.UiDbModel.get(id_)
160 if not ui:
159 if not ui:
161 raise SettingNotFound(id_)
160 raise SettingNotFound(id_)
162 Session().delete(ui)
161 Session().delete(ui)
163
162
164 def get_setting_by_name(self, name):
163 def get_setting_by_name(self, name):
165 q = self._get_settings_query()
164 q = self._get_settings_query()
166 q = q.filter(self.SettingsDbModel.app_settings_name == name)
165 q = q.filter(self.SettingsDbModel.app_settings_name == name)
167 return q.scalar()
166 return q.scalar()
168
167
169 def create_or_update_setting(
168 def create_or_update_setting(
170 self, name, val=Optional(''), type_=Optional('unicode')):
169 self, name, val=Optional(''), type_=Optional('unicode')):
171 """
170 """
172 Creates or updates RhodeCode setting. If updates is triggered it will
171 Creates or updates RhodeCode setting. If updates is triggered it will
173 only update parameters that are explicityl set Optional instance will
172 only update parameters that are explicityl set Optional instance will
174 be skipped
173 be skipped
175
174
176 :param name:
175 :param name:
177 :param val:
176 :param val:
178 :param type_:
177 :param type_:
179 :return:
178 :return:
180 """
179 """
181
180
182 res = self.get_setting_by_name(name)
181 res = self.get_setting_by_name(name)
183 repo = self._get_repo(self.repo) if self.repo else None
182 repo = self._get_repo(self.repo) if self.repo else None
184
183
185 if not res:
184 if not res:
186 val = Optional.extract(val)
185 val = Optional.extract(val)
187 type_ = Optional.extract(type_)
186 type_ = Optional.extract(type_)
188
187
189 args = (
188 args = (
190 (repo.repo_id, name, val, type_)
189 (repo.repo_id, name, val, type_)
191 if repo else (name, val, type_))
190 if repo else (name, val, type_))
192 res = self.SettingsDbModel(*args)
191 res = self.SettingsDbModel(*args)
193
192
194 else:
193 else:
195 if self.repo:
194 if self.repo:
196 res.repository_id = repo.repo_id
195 res.repository_id = repo.repo_id
197
196
198 res.app_settings_name = name
197 res.app_settings_name = name
199 if not isinstance(type_, Optional):
198 if not isinstance(type_, Optional):
200 # update if set
199 # update if set
201 res.app_settings_type = type_
200 res.app_settings_type = type_
202 if not isinstance(val, Optional):
201 if not isinstance(val, Optional):
203 # update if set
202 # update if set
204 res.app_settings_value = val
203 res.app_settings_value = val
205
204
206 Session().add(res)
205 Session().add(res)
207 return res
206 return res
208
207
209 def invalidate_settings_cache(self):
208 def invalidate_settings_cache(self):
210 # NOTE:(marcink) we flush the whole sql_cache_short region, because it
209 invalidation_namespace = CacheKey.SETTINGS_INVALIDATION_NAMESPACE
211 # reads different settings etc. It's little too much but those caches are
210 CacheKey.set_invalidate(invalidation_namespace)
212 # anyway very short lived and it's a safest way.
213 region = rc_cache.get_or_create_region('sql_cache_short')
214 region.invalidate()
215
211
216 def get_all_settings(self, cache=False):
212 def get_all_settings(self, cache=False):
217 region = rc_cache.get_or_create_region('sql_cache_short')
213 region = rc_cache.get_or_create_region('sql_cache_short')
214 invalidation_namespace = CacheKey.SETTINGS_INVALIDATION_NAMESPACE
218
215
219 @region.conditional_cache_on_arguments(condition=cache)
216 @region.conditional_cache_on_arguments(condition=cache)
220 def _get_all_settings(name, key):
217 def _get_all_settings(name, key):
221 q = self._get_settings_query()
218 q = self._get_settings_query()
222 if not q:
219 if not q:
223 raise Exception('Could not get application settings !')
220 raise Exception('Could not get application settings !')
224
221
225 settings = {
222 settings = {
226 'rhodecode_' + result.app_settings_name: result.app_settings_value
223 'rhodecode_' + result.app_settings_name: result.app_settings_value
227 for result in q
224 for result in q
228 }
225 }
229 return settings
226 return settings
230
227
231 repo = self._get_repo(self.repo) if self.repo else None
228 repo = self._get_repo(self.repo) if self.repo else None
232 key = "settings_repo.{}".format(repo.repo_id) if repo else "settings_app"
229 key = "settings_repo.{}".format(repo.repo_id) if repo else "settings_app"
233 start = time.time()
230
231 inv_context_manager = rc_cache.InvalidationContext(
232 uid='cache_settings', invalidation_namespace=invalidation_namespace)
233 with inv_context_manager as invalidation_context:
234 # check for stored invalidation signal, and maybe purge the cache
235 # before computing it again
236 if invalidation_context.should_invalidate():
237 # NOTE:(marcink) we flush the whole sql_cache_short region, because it
238 # reads different settings etc. It's little too much but those caches
239 # are anyway very short lived and it's a safest way.
240 region = rc_cache.get_or_create_region('sql_cache_short')
241 region.invalidate()
242
234 result = _get_all_settings('rhodecode_settings', key)
243 result = _get_all_settings('rhodecode_settings', key)
235 total = time.time() - start
244 log.debug(
236 log.debug('Fetching app settings for key: %s took: %.3fs', key, total)
245 'Fetching app settings for key: %s took: %.3fs', key,
246 inv_context_manager.compute_time)
237
247
238 return result
248 return result
239
249
240 def get_auth_settings(self):
250 def get_auth_settings(self):
241 q = self._get_settings_query()
251 q = self._get_settings_query()
242 q = q.filter(
252 q = q.filter(
243 self.SettingsDbModel.app_settings_name.startswith('auth_'))
253 self.SettingsDbModel.app_settings_name.startswith('auth_'))
244 rows = q.all()
254 rows = q.all()
245 auth_settings = {
255 auth_settings = {
246 row.app_settings_name: row.app_settings_value for row in rows}
256 row.app_settings_name: row.app_settings_value for row in rows}
247 return auth_settings
257 return auth_settings
248
258
249 def get_auth_plugins(self):
259 def get_auth_plugins(self):
250 auth_plugins = self.get_setting_by_name("auth_plugins")
260 auth_plugins = self.get_setting_by_name("auth_plugins")
251 return auth_plugins.app_settings_value
261 return auth_plugins.app_settings_value
252
262
253 def get_default_repo_settings(self, strip_prefix=False):
263 def get_default_repo_settings(self, strip_prefix=False):
254 q = self._get_settings_query()
264 q = self._get_settings_query()
255 q = q.filter(
265 q = q.filter(
256 self.SettingsDbModel.app_settings_name.startswith('default_'))
266 self.SettingsDbModel.app_settings_name.startswith('default_'))
257 rows = q.all()
267 rows = q.all()
258
268
259 result = {}
269 result = {}
260 for row in rows:
270 for row in rows:
261 key = row.app_settings_name
271 key = row.app_settings_name
262 if strip_prefix:
272 if strip_prefix:
263 key = remove_prefix(key, prefix='default_')
273 key = remove_prefix(key, prefix='default_')
264 result.update({key: row.app_settings_value})
274 result.update({key: row.app_settings_value})
265 return result
275 return result
266
276
267 def get_repo(self):
277 def get_repo(self):
268 repo = self._get_repo(self.repo)
278 repo = self._get_repo(self.repo)
269 if not repo:
279 if not repo:
270 raise Exception(
280 raise Exception(
271 'Repository `{}` cannot be found inside the database'.format(
281 'Repository `{}` cannot be found inside the database'.format(
272 self.repo))
282 self.repo))
273 return repo
283 return repo
274
284
275 def _filter_by_repo(self, model, query):
285 def _filter_by_repo(self, model, query):
276 if self.repo:
286 if self.repo:
277 repo = self.get_repo()
287 repo = self.get_repo()
278 query = query.filter(model.repository_id == repo.repo_id)
288 query = query.filter(model.repository_id == repo.repo_id)
279 return query
289 return query
280
290
281 def _get_hooks(self, query):
291 def _get_hooks(self, query):
282 query = query.filter(self.UiDbModel.ui_section == self.HOOKS_SECTION)
292 query = query.filter(self.UiDbModel.ui_section == self.HOOKS_SECTION)
283 query = self._filter_by_repo(RepoRhodeCodeUi, query)
293 query = self._filter_by_repo(RepoRhodeCodeUi, query)
284 return query.all()
294 return query.all()
285
295
286 def _get_settings_query(self):
296 def _get_settings_query(self):
287 q = self.SettingsDbModel.query()
297 q = self.SettingsDbModel.query()
288 return self._filter_by_repo(RepoRhodeCodeSetting, q)
298 return self._filter_by_repo(RepoRhodeCodeSetting, q)
289
299
290 def list_enabled_social_plugins(self, settings):
300 def list_enabled_social_plugins(self, settings):
291 enabled = []
301 enabled = []
292 for plug in SOCIAL_PLUGINS_LIST:
302 for plug in SOCIAL_PLUGINS_LIST:
293 if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug)
303 if str2bool(settings.get('rhodecode_auth_{}_enabled'.format(plug)
294 )):
304 )):
295 enabled.append(plug)
305 enabled.append(plug)
296 return enabled
306 return enabled
297
307
298
308
299 def assert_repo_settings(func):
309 def assert_repo_settings(func):
300 @wraps(func)
310 @wraps(func)
301 def _wrapper(self, *args, **kwargs):
311 def _wrapper(self, *args, **kwargs):
302 if not self.repo_settings:
312 if not self.repo_settings:
303 raise Exception('Repository is not specified')
313 raise Exception('Repository is not specified')
304 return func(self, *args, **kwargs)
314 return func(self, *args, **kwargs)
305 return _wrapper
315 return _wrapper
306
316
307
317
308 class IssueTrackerSettingsModel(object):
318 class IssueTrackerSettingsModel(object):
309 INHERIT_SETTINGS = 'inherit_issue_tracker_settings'
319 INHERIT_SETTINGS = 'inherit_issue_tracker_settings'
310 SETTINGS_PREFIX = 'issuetracker_'
320 SETTINGS_PREFIX = 'issuetracker_'
311
321
312 def __init__(self, sa=None, repo=None):
322 def __init__(self, sa=None, repo=None):
313 self.global_settings = SettingsModel(sa=sa)
323 self.global_settings = SettingsModel(sa=sa)
314 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
324 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
315
325
316 @property
326 @property
317 def inherit_global_settings(self):
327 def inherit_global_settings(self):
318 if not self.repo_settings:
328 if not self.repo_settings:
319 return True
329 return True
320 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
330 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
321 return setting.app_settings_value if setting else True
331 return setting.app_settings_value if setting else True
322
332
323 @inherit_global_settings.setter
333 @inherit_global_settings.setter
324 def inherit_global_settings(self, value):
334 def inherit_global_settings(self, value):
325 if self.repo_settings:
335 if self.repo_settings:
326 settings = self.repo_settings.create_or_update_setting(
336 settings = self.repo_settings.create_or_update_setting(
327 self.INHERIT_SETTINGS, value, type_='bool')
337 self.INHERIT_SETTINGS, value, type_='bool')
328 Session().add(settings)
338 Session().add(settings)
329
339
330 def _get_keyname(self, key, uid, prefix=''):
340 def _get_keyname(self, key, uid, prefix=''):
331 return '{0}{1}{2}_{3}'.format(
341 return '{0}{1}{2}_{3}'.format(
332 prefix, self.SETTINGS_PREFIX, key, uid)
342 prefix, self.SETTINGS_PREFIX, key, uid)
333
343
334 def _make_dict_for_settings(self, qs):
344 def _make_dict_for_settings(self, qs):
335 prefix_match = self._get_keyname('pat', '', 'rhodecode_')
345 prefix_match = self._get_keyname('pat', '', 'rhodecode_')
336
346
337 issuetracker_entries = {}
347 issuetracker_entries = {}
338 # create keys
348 # create keys
339 for k, v in qs.items():
349 for k, v in qs.items():
340 if k.startswith(prefix_match):
350 if k.startswith(prefix_match):
341 uid = k[len(prefix_match):]
351 uid = k[len(prefix_match):]
342 issuetracker_entries[uid] = None
352 issuetracker_entries[uid] = None
343
353
344 # populate
354 # populate
345 for uid in issuetracker_entries:
355 for uid in issuetracker_entries:
346 issuetracker_entries[uid] = AttributeDict({
356 issuetracker_entries[uid] = AttributeDict({
347 'pat': qs.get(
357 'pat': qs.get(
348 self._get_keyname('pat', uid, 'rhodecode_')),
358 self._get_keyname('pat', uid, 'rhodecode_')),
349 'url': bleach.clean(
359 'url': bleach.clean(
350 qs.get(self._get_keyname('url', uid, 'rhodecode_')) or ''),
360 qs.get(self._get_keyname('url', uid, 'rhodecode_')) or ''),
351 'pref': bleach.clean(
361 'pref': bleach.clean(
352 qs.get(self._get_keyname('pref', uid, 'rhodecode_')) or ''),
362 qs.get(self._get_keyname('pref', uid, 'rhodecode_')) or ''),
353 'desc': qs.get(
363 'desc': qs.get(
354 self._get_keyname('desc', uid, 'rhodecode_')),
364 self._get_keyname('desc', uid, 'rhodecode_')),
355 })
365 })
356 return issuetracker_entries
366 return issuetracker_entries
357
367
358 def get_global_settings(self, cache=False):
368 def get_global_settings(self, cache=False):
359 """
369 """
360 Returns list of global issue tracker settings
370 Returns list of global issue tracker settings
361 """
371 """
362 defaults = self.global_settings.get_all_settings(cache=cache)
372 defaults = self.global_settings.get_all_settings(cache=cache)
363 settings = self._make_dict_for_settings(defaults)
373 settings = self._make_dict_for_settings(defaults)
364 return settings
374 return settings
365
375
366 def get_repo_settings(self, cache=False):
376 def get_repo_settings(self, cache=False):
367 """
377 """
368 Returns list of issue tracker settings per repository
378 Returns list of issue tracker settings per repository
369 """
379 """
370 if not self.repo_settings:
380 if not self.repo_settings:
371 raise Exception('Repository is not specified')
381 raise Exception('Repository is not specified')
372 all_settings = self.repo_settings.get_all_settings(cache=cache)
382 all_settings = self.repo_settings.get_all_settings(cache=cache)
373 settings = self._make_dict_for_settings(all_settings)
383 settings = self._make_dict_for_settings(all_settings)
374 return settings
384 return settings
375
385
376 def get_settings(self, cache=False):
386 def get_settings(self, cache=False):
377 if self.inherit_global_settings:
387 if self.inherit_global_settings:
378 return self.get_global_settings(cache=cache)
388 return self.get_global_settings(cache=cache)
379 else:
389 else:
380 return self.get_repo_settings(cache=cache)
390 return self.get_repo_settings(cache=cache)
381
391
382 def delete_entries(self, uid):
392 def delete_entries(self, uid):
383 if self.repo_settings:
393 if self.repo_settings:
384 all_patterns = self.get_repo_settings()
394 all_patterns = self.get_repo_settings()
385 settings_model = self.repo_settings
395 settings_model = self.repo_settings
386 else:
396 else:
387 all_patterns = self.get_global_settings()
397 all_patterns = self.get_global_settings()
388 settings_model = self.global_settings
398 settings_model = self.global_settings
389 entries = all_patterns.get(uid, [])
399 entries = all_patterns.get(uid, [])
390
400
391 for del_key in entries:
401 for del_key in entries:
392 setting_name = self._get_keyname(del_key, uid)
402 setting_name = self._get_keyname(del_key, uid)
393 entry = settings_model.get_setting_by_name(setting_name)
403 entry = settings_model.get_setting_by_name(setting_name)
394 if entry:
404 if entry:
395 Session().delete(entry)
405 Session().delete(entry)
396
406
397 Session().commit()
407 Session().commit()
398
408
399 def create_or_update_setting(
409 def create_or_update_setting(
400 self, name, val=Optional(''), type_=Optional('unicode')):
410 self, name, val=Optional(''), type_=Optional('unicode')):
401 if self.repo_settings:
411 if self.repo_settings:
402 setting = self.repo_settings.create_or_update_setting(
412 setting = self.repo_settings.create_or_update_setting(
403 name, val, type_)
413 name, val, type_)
404 else:
414 else:
405 setting = self.global_settings.create_or_update_setting(
415 setting = self.global_settings.create_or_update_setting(
406 name, val, type_)
416 name, val, type_)
407 return setting
417 return setting
408
418
409
419
410 class VcsSettingsModel(object):
420 class VcsSettingsModel(object):
411
421
412 INHERIT_SETTINGS = 'inherit_vcs_settings'
422 INHERIT_SETTINGS = 'inherit_vcs_settings'
413 GENERAL_SETTINGS = (
423 GENERAL_SETTINGS = (
414 'use_outdated_comments',
424 'use_outdated_comments',
415 'pr_merge_enabled',
425 'pr_merge_enabled',
416 'hg_use_rebase_for_merging',
426 'hg_use_rebase_for_merging',
417 'hg_close_branch_before_merging',
427 'hg_close_branch_before_merging',
418 'git_use_rebase_for_merging',
428 'git_use_rebase_for_merging',
419 'git_close_branch_before_merging',
429 'git_close_branch_before_merging',
420 'diff_cache',
430 'diff_cache',
421 )
431 )
422
432
423 HOOKS_SETTINGS = (
433 HOOKS_SETTINGS = (
424 ('hooks', 'changegroup.repo_size'),
434 ('hooks', 'changegroup.repo_size'),
425 ('hooks', 'changegroup.push_logger'),
435 ('hooks', 'changegroup.push_logger'),
426 ('hooks', 'outgoing.pull_logger'),)
436 ('hooks', 'outgoing.pull_logger'),)
427 HG_SETTINGS = (
437 HG_SETTINGS = (
428 ('extensions', 'largefiles'),
438 ('extensions', 'largefiles'),
429 ('phases', 'publish'),
439 ('phases', 'publish'),
430 ('extensions', 'evolve'),)
440 ('extensions', 'evolve'),)
431 GIT_SETTINGS = (
441 GIT_SETTINGS = (
432 ('vcs_git_lfs', 'enabled'),)
442 ('vcs_git_lfs', 'enabled'),)
433 GLOBAL_HG_SETTINGS = (
443 GLOBAL_HG_SETTINGS = (
434 ('extensions', 'largefiles'),
444 ('extensions', 'largefiles'),
435 ('largefiles', 'usercache'),
445 ('largefiles', 'usercache'),
436 ('phases', 'publish'),
446 ('phases', 'publish'),
437 ('extensions', 'hgsubversion'),
447 ('extensions', 'hgsubversion'),
438 ('extensions', 'evolve'),)
448 ('extensions', 'evolve'),)
439 GLOBAL_GIT_SETTINGS = (
449 GLOBAL_GIT_SETTINGS = (
440 ('vcs_git_lfs', 'enabled'),
450 ('vcs_git_lfs', 'enabled'),
441 ('vcs_git_lfs', 'store_location'))
451 ('vcs_git_lfs', 'store_location'))
442
452
443 GLOBAL_SVN_SETTINGS = (
453 GLOBAL_SVN_SETTINGS = (
444 ('vcs_svn_proxy', 'http_requests_enabled'),
454 ('vcs_svn_proxy', 'http_requests_enabled'),
445 ('vcs_svn_proxy', 'http_server_url'))
455 ('vcs_svn_proxy', 'http_server_url'))
446
456
447 SVN_BRANCH_SECTION = 'vcs_svn_branch'
457 SVN_BRANCH_SECTION = 'vcs_svn_branch'
448 SVN_TAG_SECTION = 'vcs_svn_tag'
458 SVN_TAG_SECTION = 'vcs_svn_tag'
449 SSL_SETTING = ('web', 'push_ssl')
459 SSL_SETTING = ('web', 'push_ssl')
450 PATH_SETTING = ('paths', '/')
460 PATH_SETTING = ('paths', '/')
451
461
452 def __init__(self, sa=None, repo=None):
462 def __init__(self, sa=None, repo=None):
453 self.global_settings = SettingsModel(sa=sa)
463 self.global_settings = SettingsModel(sa=sa)
454 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
464 self.repo_settings = SettingsModel(sa=sa, repo=repo) if repo else None
455 self._ui_settings = (
465 self._ui_settings = (
456 self.HG_SETTINGS + self.GIT_SETTINGS + self.HOOKS_SETTINGS)
466 self.HG_SETTINGS + self.GIT_SETTINGS + self.HOOKS_SETTINGS)
457 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
467 self._svn_sections = (self.SVN_BRANCH_SECTION, self.SVN_TAG_SECTION)
458
468
459 @property
469 @property
460 @assert_repo_settings
470 @assert_repo_settings
461 def inherit_global_settings(self):
471 def inherit_global_settings(self):
462 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
472 setting = self.repo_settings.get_setting_by_name(self.INHERIT_SETTINGS)
463 return setting.app_settings_value if setting else True
473 return setting.app_settings_value if setting else True
464
474
465 @inherit_global_settings.setter
475 @inherit_global_settings.setter
466 @assert_repo_settings
476 @assert_repo_settings
467 def inherit_global_settings(self, value):
477 def inherit_global_settings(self, value):
468 self.repo_settings.create_or_update_setting(
478 self.repo_settings.create_or_update_setting(
469 self.INHERIT_SETTINGS, value, type_='bool')
479 self.INHERIT_SETTINGS, value, type_='bool')
470
480
471 def get_global_svn_branch_patterns(self):
481 def get_global_svn_branch_patterns(self):
472 return self.global_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
482 return self.global_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
473
483
474 @assert_repo_settings
484 @assert_repo_settings
475 def get_repo_svn_branch_patterns(self):
485 def get_repo_svn_branch_patterns(self):
476 return self.repo_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
486 return self.repo_settings.get_ui_by_section(self.SVN_BRANCH_SECTION)
477
487
478 def get_global_svn_tag_patterns(self):
488 def get_global_svn_tag_patterns(self):
479 return self.global_settings.get_ui_by_section(self.SVN_TAG_SECTION)
489 return self.global_settings.get_ui_by_section(self.SVN_TAG_SECTION)
480
490
481 @assert_repo_settings
491 @assert_repo_settings
482 def get_repo_svn_tag_patterns(self):
492 def get_repo_svn_tag_patterns(self):
483 return self.repo_settings.get_ui_by_section(self.SVN_TAG_SECTION)
493 return self.repo_settings.get_ui_by_section(self.SVN_TAG_SECTION)
484
494
485 def get_global_settings(self):
495 def get_global_settings(self):
486 return self._collect_all_settings(global_=True)
496 return self._collect_all_settings(global_=True)
487
497
488 @assert_repo_settings
498 @assert_repo_settings
489 def get_repo_settings(self):
499 def get_repo_settings(self):
490 return self._collect_all_settings(global_=False)
500 return self._collect_all_settings(global_=False)
491
501
492 @assert_repo_settings
502 @assert_repo_settings
493 def create_or_update_repo_settings(
503 def create_or_update_repo_settings(
494 self, data, inherit_global_settings=False):
504 self, data, inherit_global_settings=False):
495 from rhodecode.model.scm import ScmModel
505 from rhodecode.model.scm import ScmModel
496
506
497 self.inherit_global_settings = inherit_global_settings
507 self.inherit_global_settings = inherit_global_settings
498
508
499 repo = self.repo_settings.get_repo()
509 repo = self.repo_settings.get_repo()
500 if not inherit_global_settings:
510 if not inherit_global_settings:
501 if repo.repo_type == 'svn':
511 if repo.repo_type == 'svn':
502 self.create_repo_svn_settings(data)
512 self.create_repo_svn_settings(data)
503 else:
513 else:
504 self.create_or_update_repo_hook_settings(data)
514 self.create_or_update_repo_hook_settings(data)
505 self.create_or_update_repo_pr_settings(data)
515 self.create_or_update_repo_pr_settings(data)
506
516
507 if repo.repo_type == 'hg':
517 if repo.repo_type == 'hg':
508 self.create_or_update_repo_hg_settings(data)
518 self.create_or_update_repo_hg_settings(data)
509
519
510 if repo.repo_type == 'git':
520 if repo.repo_type == 'git':
511 self.create_or_update_repo_git_settings(data)
521 self.create_or_update_repo_git_settings(data)
512
522
513 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
523 ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
514
524
515 @assert_repo_settings
525 @assert_repo_settings
516 def create_or_update_repo_hook_settings(self, data):
526 def create_or_update_repo_hook_settings(self, data):
517 for section, key in self.HOOKS_SETTINGS:
527 for section, key in self.HOOKS_SETTINGS:
518 data_key = self._get_form_ui_key(section, key)
528 data_key = self._get_form_ui_key(section, key)
519 if data_key not in data:
529 if data_key not in data:
520 raise ValueError(
530 raise ValueError(
521 'The given data does not contain {} key'.format(data_key))
531 'The given data does not contain {} key'.format(data_key))
522
532
523 active = data.get(data_key)
533 active = data.get(data_key)
524 repo_setting = self.repo_settings.get_ui_by_section_and_key(
534 repo_setting = self.repo_settings.get_ui_by_section_and_key(
525 section, key)
535 section, key)
526 if not repo_setting:
536 if not repo_setting:
527 global_setting = self.global_settings.\
537 global_setting = self.global_settings.\
528 get_ui_by_section_and_key(section, key)
538 get_ui_by_section_and_key(section, key)
529 self.repo_settings.create_ui_section_value(
539 self.repo_settings.create_ui_section_value(
530 section, global_setting.ui_value, key=key, active=active)
540 section, global_setting.ui_value, key=key, active=active)
531 else:
541 else:
532 repo_setting.ui_active = active
542 repo_setting.ui_active = active
533 Session().add(repo_setting)
543 Session().add(repo_setting)
534
544
535 def update_global_hook_settings(self, data):
545 def update_global_hook_settings(self, data):
536 for section, key in self.HOOKS_SETTINGS:
546 for section, key in self.HOOKS_SETTINGS:
537 data_key = self._get_form_ui_key(section, key)
547 data_key = self._get_form_ui_key(section, key)
538 if data_key not in data:
548 if data_key not in data:
539 raise ValueError(
549 raise ValueError(
540 'The given data does not contain {} key'.format(data_key))
550 'The given data does not contain {} key'.format(data_key))
541 active = data.get(data_key)
551 active = data.get(data_key)
542 repo_setting = self.global_settings.get_ui_by_section_and_key(
552 repo_setting = self.global_settings.get_ui_by_section_and_key(
543 section, key)
553 section, key)
544 repo_setting.ui_active = active
554 repo_setting.ui_active = active
545 Session().add(repo_setting)
555 Session().add(repo_setting)
546
556
547 @assert_repo_settings
557 @assert_repo_settings
548 def create_or_update_repo_pr_settings(self, data):
558 def create_or_update_repo_pr_settings(self, data):
549 return self._create_or_update_general_settings(
559 return self._create_or_update_general_settings(
550 self.repo_settings, data)
560 self.repo_settings, data)
551
561
552 def create_or_update_global_pr_settings(self, data):
562 def create_or_update_global_pr_settings(self, data):
553 return self._create_or_update_general_settings(
563 return self._create_or_update_general_settings(
554 self.global_settings, data)
564 self.global_settings, data)
555
565
556 @assert_repo_settings
566 @assert_repo_settings
557 def create_repo_svn_settings(self, data):
567 def create_repo_svn_settings(self, data):
558 return self._create_svn_settings(self.repo_settings, data)
568 return self._create_svn_settings(self.repo_settings, data)
559
569
560 @assert_repo_settings
570 @assert_repo_settings
561 def create_or_update_repo_hg_settings(self, data):
571 def create_or_update_repo_hg_settings(self, data):
562 largefiles, phases, evolve = \
572 largefiles, phases, evolve = \
563 self.HG_SETTINGS
573 self.HG_SETTINGS
564 largefiles_key, phases_key, evolve_key = \
574 largefiles_key, phases_key, evolve_key = \
565 self._get_settings_keys(self.HG_SETTINGS, data)
575 self._get_settings_keys(self.HG_SETTINGS, data)
566
576
567 self._create_or_update_ui(
577 self._create_or_update_ui(
568 self.repo_settings, *largefiles, value='',
578 self.repo_settings, *largefiles, value='',
569 active=data[largefiles_key])
579 active=data[largefiles_key])
570 self._create_or_update_ui(
580 self._create_or_update_ui(
571 self.repo_settings, *evolve, value='',
581 self.repo_settings, *evolve, value='',
572 active=data[evolve_key])
582 active=data[evolve_key])
573 self._create_or_update_ui(
583 self._create_or_update_ui(
574 self.repo_settings, *phases, value=safe_str(data[phases_key]))
584 self.repo_settings, *phases, value=safe_str(data[phases_key]))
575
585
576
586
577 def create_or_update_global_hg_settings(self, data):
587 def create_or_update_global_hg_settings(self, data):
578 largefiles, largefiles_store, phases, hgsubversion, evolve \
588 largefiles, largefiles_store, phases, hgsubversion, evolve \
579 = self.GLOBAL_HG_SETTINGS
589 = self.GLOBAL_HG_SETTINGS
580 largefiles_key, largefiles_store_key, phases_key, subversion_key, evolve_key \
590 largefiles_key, largefiles_store_key, phases_key, subversion_key, evolve_key \
581 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS, data)
591 = self._get_settings_keys(self.GLOBAL_HG_SETTINGS, data)
582
592
583 self._create_or_update_ui(
593 self._create_or_update_ui(
584 self.global_settings, *largefiles, value='',
594 self.global_settings, *largefiles, value='',
585 active=data[largefiles_key])
595 active=data[largefiles_key])
586 self._create_or_update_ui(
596 self._create_or_update_ui(
587 self.global_settings, *largefiles_store,
597 self.global_settings, *largefiles_store,
588 value=data[largefiles_store_key])
598 value=data[largefiles_store_key])
589 self._create_or_update_ui(
599 self._create_or_update_ui(
590 self.global_settings, *phases, value=safe_str(data[phases_key]))
600 self.global_settings, *phases, value=safe_str(data[phases_key]))
591 self._create_or_update_ui(
601 self._create_or_update_ui(
592 self.global_settings, *hgsubversion, active=data[subversion_key])
602 self.global_settings, *hgsubversion, active=data[subversion_key])
593 self._create_or_update_ui(
603 self._create_or_update_ui(
594 self.global_settings, *evolve, value='',
604 self.global_settings, *evolve, value='',
595 active=data[evolve_key])
605 active=data[evolve_key])
596
606
597 def create_or_update_repo_git_settings(self, data):
607 def create_or_update_repo_git_settings(self, data):
598 # NOTE(marcink): # comma make unpack work properly
608 # NOTE(marcink): # comma make unpack work properly
599 lfs_enabled, \
609 lfs_enabled, \
600 = self.GIT_SETTINGS
610 = self.GIT_SETTINGS
601
611
602 lfs_enabled_key, \
612 lfs_enabled_key, \
603 = self._get_settings_keys(self.GIT_SETTINGS, data)
613 = self._get_settings_keys(self.GIT_SETTINGS, data)
604
614
605 self._create_or_update_ui(
615 self._create_or_update_ui(
606 self.repo_settings, *lfs_enabled, value=data[lfs_enabled_key],
616 self.repo_settings, *lfs_enabled, value=data[lfs_enabled_key],
607 active=data[lfs_enabled_key])
617 active=data[lfs_enabled_key])
608
618
609 def create_or_update_global_git_settings(self, data):
619 def create_or_update_global_git_settings(self, data):
610 lfs_enabled, lfs_store_location \
620 lfs_enabled, lfs_store_location \
611 = self.GLOBAL_GIT_SETTINGS
621 = self.GLOBAL_GIT_SETTINGS
612 lfs_enabled_key, lfs_store_location_key \
622 lfs_enabled_key, lfs_store_location_key \
613 = self._get_settings_keys(self.GLOBAL_GIT_SETTINGS, data)
623 = self._get_settings_keys(self.GLOBAL_GIT_SETTINGS, data)
614
624
615 self._create_or_update_ui(
625 self._create_or_update_ui(
616 self.global_settings, *lfs_enabled, value=data[lfs_enabled_key],
626 self.global_settings, *lfs_enabled, value=data[lfs_enabled_key],
617 active=data[lfs_enabled_key])
627 active=data[lfs_enabled_key])
618 self._create_or_update_ui(
628 self._create_or_update_ui(
619 self.global_settings, *lfs_store_location,
629 self.global_settings, *lfs_store_location,
620 value=data[lfs_store_location_key])
630 value=data[lfs_store_location_key])
621
631
622 def create_or_update_global_svn_settings(self, data):
632 def create_or_update_global_svn_settings(self, data):
623 # branch/tags patterns
633 # branch/tags patterns
624 self._create_svn_settings(self.global_settings, data)
634 self._create_svn_settings(self.global_settings, data)
625
635
626 http_requests_enabled, http_server_url = self.GLOBAL_SVN_SETTINGS
636 http_requests_enabled, http_server_url = self.GLOBAL_SVN_SETTINGS
627 http_requests_enabled_key, http_server_url_key = self._get_settings_keys(
637 http_requests_enabled_key, http_server_url_key = self._get_settings_keys(
628 self.GLOBAL_SVN_SETTINGS, data)
638 self.GLOBAL_SVN_SETTINGS, data)
629
639
630 self._create_or_update_ui(
640 self._create_or_update_ui(
631 self.global_settings, *http_requests_enabled,
641 self.global_settings, *http_requests_enabled,
632 value=safe_str(data[http_requests_enabled_key]))
642 value=safe_str(data[http_requests_enabled_key]))
633 self._create_or_update_ui(
643 self._create_or_update_ui(
634 self.global_settings, *http_server_url,
644 self.global_settings, *http_server_url,
635 value=data[http_server_url_key])
645 value=data[http_server_url_key])
636
646
637 def update_global_ssl_setting(self, value):
647 def update_global_ssl_setting(self, value):
638 self._create_or_update_ui(
648 self._create_or_update_ui(
639 self.global_settings, *self.SSL_SETTING, value=value)
649 self.global_settings, *self.SSL_SETTING, value=value)
640
650
641 def update_global_path_setting(self, value):
651 def update_global_path_setting(self, value):
642 self._create_or_update_ui(
652 self._create_or_update_ui(
643 self.global_settings, *self.PATH_SETTING, value=value)
653 self.global_settings, *self.PATH_SETTING, value=value)
644
654
645 @assert_repo_settings
655 @assert_repo_settings
646 def delete_repo_svn_pattern(self, id_):
656 def delete_repo_svn_pattern(self, id_):
647 ui = self.repo_settings.UiDbModel.get(id_)
657 ui = self.repo_settings.UiDbModel.get(id_)
648 if ui and ui.repository.repo_name == self.repo_settings.repo:
658 if ui and ui.repository.repo_name == self.repo_settings.repo:
649 # only delete if it's the same repo as initialized settings
659 # only delete if it's the same repo as initialized settings
650 self.repo_settings.delete_ui(id_)
660 self.repo_settings.delete_ui(id_)
651 else:
661 else:
652 # raise error as if we wouldn't find this option
662 # raise error as if we wouldn't find this option
653 self.repo_settings.delete_ui(-1)
663 self.repo_settings.delete_ui(-1)
654
664
655 def delete_global_svn_pattern(self, id_):
665 def delete_global_svn_pattern(self, id_):
656 self.global_settings.delete_ui(id_)
666 self.global_settings.delete_ui(id_)
657
667
658 @assert_repo_settings
668 @assert_repo_settings
659 def get_repo_ui_settings(self, section=None, key=None):
669 def get_repo_ui_settings(self, section=None, key=None):
660 global_uis = self.global_settings.get_ui(section, key)
670 global_uis = self.global_settings.get_ui(section, key)
661 repo_uis = self.repo_settings.get_ui(section, key)
671 repo_uis = self.repo_settings.get_ui(section, key)
662 filtered_repo_uis = self._filter_ui_settings(repo_uis)
672 filtered_repo_uis = self._filter_ui_settings(repo_uis)
663 filtered_repo_uis_keys = [
673 filtered_repo_uis_keys = [
664 (s.section, s.key) for s in filtered_repo_uis]
674 (s.section, s.key) for s in filtered_repo_uis]
665
675
666 def _is_global_ui_filtered(ui):
676 def _is_global_ui_filtered(ui):
667 return (
677 return (
668 (ui.section, ui.key) in filtered_repo_uis_keys
678 (ui.section, ui.key) in filtered_repo_uis_keys
669 or ui.section in self._svn_sections)
679 or ui.section in self._svn_sections)
670
680
671 filtered_global_uis = [
681 filtered_global_uis = [
672 ui for ui in global_uis if not _is_global_ui_filtered(ui)]
682 ui for ui in global_uis if not _is_global_ui_filtered(ui)]
673
683
674 return filtered_global_uis + filtered_repo_uis
684 return filtered_global_uis + filtered_repo_uis
675
685
676 def get_global_ui_settings(self, section=None, key=None):
686 def get_global_ui_settings(self, section=None, key=None):
677 return self.global_settings.get_ui(section, key)
687 return self.global_settings.get_ui(section, key)
678
688
679 def get_ui_settings_as_config_obj(self, section=None, key=None):
689 def get_ui_settings_as_config_obj(self, section=None, key=None):
680 config = base.Config()
690 config = base.Config()
681
691
682 ui_settings = self.get_ui_settings(section=section, key=key)
692 ui_settings = self.get_ui_settings(section=section, key=key)
683
693
684 for entry in ui_settings:
694 for entry in ui_settings:
685 config.set(entry.section, entry.key, entry.value)
695 config.set(entry.section, entry.key, entry.value)
686
696
687 return config
697 return config
688
698
689 def get_ui_settings(self, section=None, key=None):
699 def get_ui_settings(self, section=None, key=None):
690 if not self.repo_settings or self.inherit_global_settings:
700 if not self.repo_settings or self.inherit_global_settings:
691 return self.get_global_ui_settings(section, key)
701 return self.get_global_ui_settings(section, key)
692 else:
702 else:
693 return self.get_repo_ui_settings(section, key)
703 return self.get_repo_ui_settings(section, key)
694
704
695 def get_svn_patterns(self, section=None):
705 def get_svn_patterns(self, section=None):
696 if not self.repo_settings:
706 if not self.repo_settings:
697 return self.get_global_ui_settings(section)
707 return self.get_global_ui_settings(section)
698 else:
708 else:
699 return self.get_repo_ui_settings(section)
709 return self.get_repo_ui_settings(section)
700
710
701 @assert_repo_settings
711 @assert_repo_settings
702 def get_repo_general_settings(self):
712 def get_repo_general_settings(self):
703 global_settings = self.global_settings.get_all_settings()
713 global_settings = self.global_settings.get_all_settings()
704 repo_settings = self.repo_settings.get_all_settings()
714 repo_settings = self.repo_settings.get_all_settings()
705 filtered_repo_settings = self._filter_general_settings(repo_settings)
715 filtered_repo_settings = self._filter_general_settings(repo_settings)
706 global_settings.update(filtered_repo_settings)
716 global_settings.update(filtered_repo_settings)
707 return global_settings
717 return global_settings
708
718
709 def get_global_general_settings(self):
719 def get_global_general_settings(self):
710 return self.global_settings.get_all_settings()
720 return self.global_settings.get_all_settings()
711
721
712 def get_general_settings(self):
722 def get_general_settings(self):
713 if not self.repo_settings or self.inherit_global_settings:
723 if not self.repo_settings or self.inherit_global_settings:
714 return self.get_global_general_settings()
724 return self.get_global_general_settings()
715 else:
725 else:
716 return self.get_repo_general_settings()
726 return self.get_repo_general_settings()
717
727
718 def get_repos_location(self):
728 def get_repos_location(self):
719 return self.global_settings.get_ui_by_key('/').ui_value
729 return self.global_settings.get_ui_by_key('/').ui_value
720
730
721 def _filter_ui_settings(self, settings):
731 def _filter_ui_settings(self, settings):
722 filtered_settings = [
732 filtered_settings = [
723 s for s in settings if self._should_keep_setting(s)]
733 s for s in settings if self._should_keep_setting(s)]
724 return filtered_settings
734 return filtered_settings
725
735
726 def _should_keep_setting(self, setting):
736 def _should_keep_setting(self, setting):
727 keep = (
737 keep = (
728 (setting.section, setting.key) in self._ui_settings or
738 (setting.section, setting.key) in self._ui_settings or
729 setting.section in self._svn_sections)
739 setting.section in self._svn_sections)
730 return keep
740 return keep
731
741
732 def _filter_general_settings(self, settings):
742 def _filter_general_settings(self, settings):
733 keys = ['rhodecode_{}'.format(key) for key in self.GENERAL_SETTINGS]
743 keys = ['rhodecode_{}'.format(key) for key in self.GENERAL_SETTINGS]
734 return {
744 return {
735 k: settings[k]
745 k: settings[k]
736 for k in settings if k in keys}
746 for k in settings if k in keys}
737
747
738 def _collect_all_settings(self, global_=False):
748 def _collect_all_settings(self, global_=False):
739 settings = self.global_settings if global_ else self.repo_settings
749 settings = self.global_settings if global_ else self.repo_settings
740 result = {}
750 result = {}
741
751
742 for section, key in self._ui_settings:
752 for section, key in self._ui_settings:
743 ui = settings.get_ui_by_section_and_key(section, key)
753 ui = settings.get_ui_by_section_and_key(section, key)
744 result_key = self._get_form_ui_key(section, key)
754 result_key = self._get_form_ui_key(section, key)
745
755
746 if ui:
756 if ui:
747 if section in ('hooks', 'extensions'):
757 if section in ('hooks', 'extensions'):
748 result[result_key] = ui.ui_active
758 result[result_key] = ui.ui_active
749 elif result_key in ['vcs_git_lfs_enabled']:
759 elif result_key in ['vcs_git_lfs_enabled']:
750 result[result_key] = ui.ui_active
760 result[result_key] = ui.ui_active
751 else:
761 else:
752 result[result_key] = ui.ui_value
762 result[result_key] = ui.ui_value
753
763
754 for name in self.GENERAL_SETTINGS:
764 for name in self.GENERAL_SETTINGS:
755 setting = settings.get_setting_by_name(name)
765 setting = settings.get_setting_by_name(name)
756 if setting:
766 if setting:
757 result_key = 'rhodecode_{}'.format(name)
767 result_key = 'rhodecode_{}'.format(name)
758 result[result_key] = setting.app_settings_value
768 result[result_key] = setting.app_settings_value
759
769
760 return result
770 return result
761
771
762 def _get_form_ui_key(self, section, key):
772 def _get_form_ui_key(self, section, key):
763 return '{section}_{key}'.format(
773 return '{section}_{key}'.format(
764 section=section, key=key.replace('.', '_'))
774 section=section, key=key.replace('.', '_'))
765
775
766 def _create_or_update_ui(
776 def _create_or_update_ui(
767 self, settings, section, key, value=None, active=None):
777 self, settings, section, key, value=None, active=None):
768 ui = settings.get_ui_by_section_and_key(section, key)
778 ui = settings.get_ui_by_section_and_key(section, key)
769 if not ui:
779 if not ui:
770 active = True if active is None else active
780 active = True if active is None else active
771 settings.create_ui_section_value(
781 settings.create_ui_section_value(
772 section, value, key=key, active=active)
782 section, value, key=key, active=active)
773 else:
783 else:
774 if active is not None:
784 if active is not None:
775 ui.ui_active = active
785 ui.ui_active = active
776 if value is not None:
786 if value is not None:
777 ui.ui_value = value
787 ui.ui_value = value
778 Session().add(ui)
788 Session().add(ui)
779
789
780 def _create_svn_settings(self, settings, data):
790 def _create_svn_settings(self, settings, data):
781 svn_settings = {
791 svn_settings = {
782 'new_svn_branch': self.SVN_BRANCH_SECTION,
792 'new_svn_branch': self.SVN_BRANCH_SECTION,
783 'new_svn_tag': self.SVN_TAG_SECTION
793 'new_svn_tag': self.SVN_TAG_SECTION
784 }
794 }
785 for key in svn_settings:
795 for key in svn_settings:
786 if data.get(key):
796 if data.get(key):
787 settings.create_ui_section_value(svn_settings[key], data[key])
797 settings.create_ui_section_value(svn_settings[key], data[key])
788
798
789 def _create_or_update_general_settings(self, settings, data):
799 def _create_or_update_general_settings(self, settings, data):
790 for name in self.GENERAL_SETTINGS:
800 for name in self.GENERAL_SETTINGS:
791 data_key = 'rhodecode_{}'.format(name)
801 data_key = 'rhodecode_{}'.format(name)
792 if data_key not in data:
802 if data_key not in data:
793 raise ValueError(
803 raise ValueError(
794 'The given data does not contain {} key'.format(data_key))
804 'The given data does not contain {} key'.format(data_key))
795 setting = settings.create_or_update_setting(
805 setting = settings.create_or_update_setting(
796 name, data[data_key], 'bool')
806 name, data[data_key], 'bool')
797 Session().add(setting)
807 Session().add(setting)
798
808
799 def _get_settings_keys(self, settings, data):
809 def _get_settings_keys(self, settings, data):
800 data_keys = [self._get_form_ui_key(*s) for s in settings]
810 data_keys = [self._get_form_ui_key(*s) for s in settings]
801 for data_key in data_keys:
811 for data_key in data_keys:
802 if data_key not in data:
812 if data_key not in data:
803 raise ValueError(
813 raise ValueError(
804 'The given data does not contain {} key'.format(data_key))
814 'The given data does not contain {} key'.format(data_key))
805 return data_keys
815 return data_keys
806
816
807 def create_largeobjects_dirs_if_needed(self, repo_store_path):
817 def create_largeobjects_dirs_if_needed(self, repo_store_path):
808 """
818 """
809 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
819 This is subscribed to the `pyramid.events.ApplicationCreated` event. It
810 does a repository scan if enabled in the settings.
820 does a repository scan if enabled in the settings.
811 """
821 """
812
822
813 from rhodecode.lib.vcs.backends.hg import largefiles_store
823 from rhodecode.lib.vcs.backends.hg import largefiles_store
814 from rhodecode.lib.vcs.backends.git import lfs_store
824 from rhodecode.lib.vcs.backends.git import lfs_store
815
825
816 paths = [
826 paths = [
817 largefiles_store(repo_store_path),
827 largefiles_store(repo_store_path),
818 lfs_store(repo_store_path)]
828 lfs_store(repo_store_path)]
819
829
820 for path in paths:
830 for path in paths:
821 if os.path.isdir(path):
831 if os.path.isdir(path):
822 continue
832 continue
823 if os.path.isfile(path):
833 if os.path.isfile(path):
824 continue
834 continue
825 # not a file nor dir, we try to create it
835 # not a file nor dir, we try to create it
826 try:
836 try:
827 os.makedirs(path)
837 os.makedirs(path)
828 except Exception:
838 except Exception:
829 log.warning('Failed to create largefiles dir:%s', path)
839 log.warning('Failed to create largefiles dir:%s', path)
General Comments 0
You need to be logged in to leave comments. Login now