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