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