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