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