Mercurial > kallithea
comparison rhodecode/lib/utils.py @ 2031:82a88013a3fd
merge 1.3 into stable
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sun, 26 Feb 2012 17:25:09 +0200 |
parents | 6b318706f712 3a014a84a2db |
children | 9ab21c5ddb84 |
comparison
equal
deleted
inserted
replaced
2005:ab0e122b38a7 | 2031:82a88013a3fd |
---|---|
5 | 5 |
6 Utilities library for RhodeCode | 6 Utilities library for RhodeCode |
7 | 7 |
8 :created_on: Apr 18, 2010 | 8 :created_on: Apr 18, 2010 |
9 :author: marcink | 9 :author: marcink |
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com> | 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com> |
11 :license: GPLv3, see COPYING for more details. | 11 :license: GPLv3, see COPYING for more details. |
12 """ | 12 """ |
13 # This program is free software: you can redistribute it and/or modify | 13 # This program is free software: you can redistribute it and/or modify |
14 # it under the terms of the GNU General Public License as published by | 14 # it under the terms of the GNU General Public License as published by |
15 # the Free Software Foundation, either version 3 of the License, or | 15 # the Free Software Foundation, either version 3 of the License, or |
27 import logging | 27 import logging |
28 import datetime | 28 import datetime |
29 import traceback | 29 import traceback |
30 import paste | 30 import paste |
31 import beaker | 31 import beaker |
32 import tarfile | |
33 import shutil | |
34 from os.path import abspath | |
32 from os.path import dirname as dn, join as jn | 35 from os.path import dirname as dn, join as jn |
33 | 36 |
34 from paste.script.command import Command, BadCommand | 37 from paste.script.command import Command, BadCommand |
35 | 38 |
36 from mercurial import ui, config | 39 from mercurial import ui, config |
37 | 40 |
38 from webhelpers.text import collapse, remove_formatting, strip_tags | 41 from webhelpers.text import collapse, remove_formatting, strip_tags |
39 | 42 |
40 from vcs import get_backend | 43 from rhodecode.lib.vcs import get_backend |
41 from vcs.backends.base import BaseChangeset | 44 from rhodecode.lib.vcs.backends.base import BaseChangeset |
42 from vcs.utils.lazy import LazyProperty | 45 from rhodecode.lib.vcs.utils.lazy import LazyProperty |
43 from vcs.utils.helpers import get_scm | 46 from rhodecode.lib.vcs.utils.helpers import get_scm |
44 from vcs.exceptions import VCSError | 47 from rhodecode.lib.vcs.exceptions import VCSError |
48 | |
49 from rhodecode.lib.caching_query import FromCache | |
45 | 50 |
46 from rhodecode.model import meta | 51 from rhodecode.model import meta |
47 from rhodecode.model.caching_query import FromCache | 52 from rhodecode.model.db import Repository, User, RhodeCodeUi, \ |
48 from rhodecode.model.db import Repository, User, RhodeCodeUi, UserLog, Group, \ | 53 UserLog, RepoGroup, RhodeCodeSetting, UserRepoGroupToPerm |
49 RhodeCodeSettings | 54 from rhodecode.model.meta import Session |
50 from rhodecode.model.repo import RepoModel | 55 from rhodecode.model.repos_group import ReposGroupModel |
51 | 56 |
52 log = logging.getLogger(__name__) | 57 log = logging.getLogger(__name__) |
53 | 58 |
54 | 59 |
55 def recursive_replace(str, replace=' '): | 60 def recursive_replace(str_, replace=' '): |
56 """Recursive replace of given sign to just one instance | 61 """Recursive replace of given sign to just one instance |
57 | 62 |
58 :param str: given string | 63 :param str_: given string |
59 :param replace: char to find and replace multiple instances | 64 :param replace: char to find and replace multiple instances |
60 | 65 |
61 Examples:: | 66 Examples:: |
62 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-') | 67 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-') |
63 'Mighty-Mighty-Bo-sstones' | 68 'Mighty-Mighty-Bo-sstones' |
64 """ | 69 """ |
65 | 70 |
66 if str.find(replace * 2) == -1: | 71 if str_.find(replace * 2) == -1: |
67 return str | 72 return str_ |
68 else: | 73 else: |
69 str = str.replace(replace * 2, replace) | 74 str_ = str_.replace(replace * 2, replace) |
70 return recursive_replace(str, replace) | 75 return recursive_replace(str_, replace) |
71 | 76 |
72 | 77 |
73 def repo_name_slug(value): | 78 def repo_name_slug(value): |
74 """Return slug of name of repository | 79 """Return slug of name of repository |
75 This function is called on each creation/modification | 80 This function is called on each creation/modification |
88 | 93 |
89 def get_repo_slug(request): | 94 def get_repo_slug(request): |
90 return request.environ['pylons.routes_dict'].get('repo_name') | 95 return request.environ['pylons.routes_dict'].get('repo_name') |
91 | 96 |
92 | 97 |
93 def action_logger(user, action, repo, ipaddr='', sa=None): | 98 def get_repos_group_slug(request): |
99 return request.environ['pylons.routes_dict'].get('group_name') | |
100 | |
101 | |
102 def action_logger(user, action, repo, ipaddr='', sa=None, commit=False): | |
94 """ | 103 """ |
95 Action logger for various actions made by users | 104 Action logger for various actions made by users |
96 | 105 |
97 :param user: user that made this action, can be a unique username string or | 106 :param user: user that made this action, can be a unique username string or |
98 object containing user_id attribute | 107 object containing user_id attribute |
104 :param sa: optional sqlalchemy session | 113 :param sa: optional sqlalchemy session |
105 | 114 |
106 """ | 115 """ |
107 | 116 |
108 if not sa: | 117 if not sa: |
109 sa = meta.Session() | 118 sa = meta.Session |
110 | 119 |
111 try: | 120 try: |
112 if hasattr(user, 'user_id'): | 121 if hasattr(user, 'user_id'): |
113 user_obj = user | 122 user_obj = user |
114 elif isinstance(user, basestring): | 123 elif isinstance(user, basestring): |
115 user_obj = User.get_by_username(user) | 124 user_obj = User.get_by_username(user) |
116 else: | 125 else: |
117 raise Exception('You have to provide user object or username') | 126 raise Exception('You have to provide user object or username') |
118 | 127 |
119 rm = RepoModel() | |
120 if hasattr(repo, 'repo_id'): | 128 if hasattr(repo, 'repo_id'): |
121 repo_obj = rm.get(repo.repo_id, cache=False) | 129 repo_obj = Repository.get(repo.repo_id) |
122 repo_name = repo_obj.repo_name | 130 repo_name = repo_obj.repo_name |
123 elif isinstance(repo, basestring): | 131 elif isinstance(repo, basestring): |
124 repo_name = repo.lstrip('/') | 132 repo_name = repo.lstrip('/') |
125 repo_obj = rm.get_by_repo_name(repo_name, cache=False) | 133 repo_obj = Repository.get_by_repo_name(repo_name) |
126 else: | 134 else: |
127 raise Exception('You have to provide repository to action logger') | 135 raise Exception('You have to provide repository to action logger') |
128 | 136 |
129 user_log = UserLog() | 137 user_log = UserLog() |
130 user_log.user_id = user_obj.user_id | 138 user_log.user_id = user_obj.user_id |
134 user_log.repository_name = repo_name | 142 user_log.repository_name = repo_name |
135 | 143 |
136 user_log.action_date = datetime.datetime.now() | 144 user_log.action_date = datetime.datetime.now() |
137 user_log.user_ip = ipaddr | 145 user_log.user_ip = ipaddr |
138 sa.add(user_log) | 146 sa.add(user_log) |
139 sa.commit() | 147 |
140 | 148 log.info('Adding user %s, action %s on %s' % (user_obj, action, repo)) |
141 log.info('Adding user %s, action %s on %s', user_obj, action, repo) | 149 if commit: |
150 sa.commit() | |
142 except: | 151 except: |
143 log.error(traceback.format_exc()) | 152 log.error(traceback.format_exc()) |
144 sa.rollback() | 153 raise |
145 | 154 |
146 | 155 |
147 def get_repos(path, recursive=False): | 156 def get_repos(path, recursive=False): |
148 """ | 157 """ |
149 Scans given path for repos and return (name,(type,path)) tuple | 158 Scans given path for repos and return (name,(type,path)) tuple |
150 | 159 |
151 :param path: path to scann for repositories | 160 :param path: path to scan for repositories |
152 :param recursive: recursive search and return names with subdirs in front | 161 :param recursive: recursive search and return names with subdirs in front |
153 """ | 162 """ |
154 from vcs.utils.helpers import get_scm | |
155 from vcs.exceptions import VCSError | |
156 | 163 |
157 # remove ending slash for better results | 164 # remove ending slash for better results |
158 path = path.rstrip('/') | 165 path = path.rstrip(os.sep) |
159 | 166 |
160 def _get_repos(p): | 167 def _get_repos(p): |
161 if not os.access(p, os.W_OK): | 168 if not os.access(p, os.W_OK): |
162 return | 169 return |
163 for dirpath in os.listdir(p): | 170 for dirpath in os.listdir(p): |
193 get_scm(full_path) | 200 get_scm(full_path) |
194 return True | 201 return True |
195 except VCSError: | 202 except VCSError: |
196 return False | 203 return False |
197 | 204 |
205 | |
198 def is_valid_repos_group(repos_group_name, base_path): | 206 def is_valid_repos_group(repos_group_name, base_path): |
199 """ | 207 """ |
200 Returns True if given path is a repos group False otherwise | 208 Returns True if given path is a repos group False otherwise |
201 | 209 |
202 :param repo_name: | 210 :param repo_name: |
203 :param base_path: | 211 :param base_path: |
204 """ | 212 """ |
205 full_path = os.path.join(base_path, repos_group_name) | 213 full_path = os.path.join(base_path, repos_group_name) |
206 | 214 |
211 # check if it's a valid path | 219 # check if it's a valid path |
212 if os.path.isdir(full_path): | 220 if os.path.isdir(full_path): |
213 return True | 221 return True |
214 | 222 |
215 return False | 223 return False |
224 | |
216 | 225 |
217 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): | 226 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): |
218 while True: | 227 while True: |
219 ok = raw_input(prompt) | 228 ok = raw_input(prompt) |
220 if ok in ('y', 'ye', 'yes'): | 229 if ok in ('y', 'ye', 'yes'): |
248 :param read_from: read from 'file' or 'db' | 257 :param read_from: read from 'file' or 'db' |
249 """ | 258 """ |
250 | 259 |
251 baseui = ui.ui() | 260 baseui = ui.ui() |
252 | 261 |
253 #clean the baseui object | 262 # clean the baseui object |
254 baseui._ocfg = config.config() | 263 baseui._ocfg = config.config() |
255 baseui._ucfg = config.config() | 264 baseui._ucfg = config.config() |
256 baseui._tcfg = config.config() | 265 baseui._tcfg = config.config() |
257 | 266 |
258 if read_from == 'file': | 267 if read_from == 'file': |
259 if not os.path.isfile(path): | 268 if not os.path.isfile(path): |
260 log.warning('Unable to read config file %s' % path) | 269 log.debug('hgrc file is not present at %s skipping...' % path) |
261 return False | 270 return False |
262 log.debug('reading hgrc from %s', path) | 271 log.debug('reading hgrc from %s' % path) |
263 cfg = config.config() | 272 cfg = config.config() |
264 cfg.read(path) | 273 cfg.read(path) |
265 for section in ui_sections: | 274 for section in ui_sections: |
266 for k, v in cfg.items(section): | 275 for k, v in cfg.items(section): |
267 log.debug('settings ui from file[%s]%s:%s', section, k, v) | 276 log.debug('settings ui from file[%s]%s:%s' % (section, k, v)) |
268 baseui.setconfig(section, k, v) | 277 baseui.setconfig(section, k, v) |
269 | 278 |
270 elif read_from == 'db': | 279 elif read_from == 'db': |
271 sa = meta.Session() | 280 sa = meta.Session |
272 ret = sa.query(RhodeCodeUi)\ | 281 ret = sa.query(RhodeCodeUi)\ |
273 .options(FromCache("sql_cache_short", | 282 .options(FromCache("sql_cache_short", "get_hg_ui_settings"))\ |
274 "get_hg_ui_settings")).all() | 283 .all() |
275 | 284 |
276 hg_ui = ret | 285 hg_ui = ret |
277 for ui_ in hg_ui: | 286 for ui_ in hg_ui: |
278 if ui_.ui_active: | 287 if ui_.ui_active: |
279 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, | 288 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, |
283 meta.Session.remove() | 292 meta.Session.remove() |
284 return baseui | 293 return baseui |
285 | 294 |
286 | 295 |
287 def set_rhodecode_config(config): | 296 def set_rhodecode_config(config): |
288 """Updates pylons config with new settings from database | 297 """ |
298 Updates pylons config with new settings from database | |
289 | 299 |
290 :param config: | 300 :param config: |
291 """ | 301 """ |
292 hgsettings = RhodeCodeSettings.get_app_settings() | 302 hgsettings = RhodeCodeSetting.get_app_settings() |
293 | 303 |
294 for k, v in hgsettings.items(): | 304 for k, v in hgsettings.items(): |
295 config[k] = v | 305 config[k] = v |
296 | 306 |
297 | 307 |
298 def invalidate_cache(cache_key, *args): | 308 def invalidate_cache(cache_key, *args): |
299 """Puts cache invalidation task into db for | 309 """ |
310 Puts cache invalidation task into db for | |
300 further global cache invalidation | 311 further global cache invalidation |
301 """ | 312 """ |
302 | 313 |
303 from rhodecode.model.scm import ScmModel | 314 from rhodecode.model.scm import ScmModel |
304 | 315 |
311 """ | 322 """ |
312 An dummy empty changeset. It's possible to pass hash when creating | 323 An dummy empty changeset. It's possible to pass hash when creating |
313 an EmptyChangeset | 324 an EmptyChangeset |
314 """ | 325 """ |
315 | 326 |
316 def __init__(self, cs='0' * 40, repo=None, requested_revision=None, alias=None): | 327 def __init__(self, cs='0' * 40, repo=None, requested_revision=None, |
328 alias=None): | |
317 self._empty_cs = cs | 329 self._empty_cs = cs |
318 self.revision = -1 | 330 self.revision = -1 |
319 self.message = '' | 331 self.message = '' |
320 self.author = '' | 332 self.author = '' |
321 self.date = '' | 333 self.date = '' |
323 self.requested_revision = requested_revision | 335 self.requested_revision = requested_revision |
324 self.alias = alias | 336 self.alias = alias |
325 | 337 |
326 @LazyProperty | 338 @LazyProperty |
327 def raw_id(self): | 339 def raw_id(self): |
328 """Returns raw string identifying this changeset, useful for web | 340 """ |
341 Returns raw string identifying this changeset, useful for web | |
329 representation. | 342 representation. |
330 """ | 343 """ |
331 | 344 |
332 return self._empty_cs | 345 return self._empty_cs |
333 | 346 |
348 def get_file_size(self, path): | 361 def get_file_size(self, path): |
349 return 0 | 362 return 0 |
350 | 363 |
351 | 364 |
352 def map_groups(groups): | 365 def map_groups(groups): |
353 """Checks for groups existence, and creates groups structures. | 366 """ |
367 Checks for groups existence, and creates groups structures. | |
354 It returns last group in structure | 368 It returns last group in structure |
355 | 369 |
356 :param groups: list of groups structure | 370 :param groups: list of groups structure |
357 """ | 371 """ |
358 sa = meta.Session() | 372 sa = meta.Session |
359 | 373 |
360 parent = None | 374 parent = None |
361 group = None | 375 group = None |
362 | 376 |
363 # last element is repo in nested groups structure | 377 # last element is repo in nested groups structure |
364 groups = groups[:-1] | 378 groups = groups[:-1] |
365 | 379 rgm = ReposGroupModel(sa) |
366 for lvl, group_name in enumerate(groups): | 380 for lvl, group_name in enumerate(groups): |
367 group_name = '/'.join(groups[:lvl] + [group_name]) | 381 group_name = '/'.join(groups[:lvl] + [group_name]) |
368 group = sa.query(Group).filter(Group.group_name == group_name).scalar() | 382 group = RepoGroup.get_by_group_name(group_name) |
383 desc = '%s group' % group_name | |
384 | |
385 # # WTF that doesn't work !? | |
386 # if group is None: | |
387 # group = rgm.create(group_name, desc, parent, just_db=True) | |
388 # sa.commit() | |
369 | 389 |
370 if group is None: | 390 if group is None: |
371 group = Group(group_name, parent) | 391 log.debug('creating group level: %s group_name: %s' % (lvl, group_name)) |
392 group = RepoGroup(group_name, parent) | |
393 group.group_description = desc | |
372 sa.add(group) | 394 sa.add(group) |
395 rgm._create_default_perms(group) | |
373 sa.commit() | 396 sa.commit() |
374 parent = group | 397 parent = group |
375 return group | 398 return group |
376 | 399 |
377 | 400 |
378 def repo2db_mapper(initial_repo_list, remove_obsolete=False): | 401 def repo2db_mapper(initial_repo_list, remove_obsolete=False): |
379 """maps all repos given in initial_repo_list, non existing repositories | 402 """ |
403 maps all repos given in initial_repo_list, non existing repositories | |
380 are created, if remove_obsolete is True it also check for db entries | 404 are created, if remove_obsolete is True it also check for db entries |
381 that are not in initial_repo_list and removes them. | 405 that are not in initial_repo_list and removes them. |
382 | 406 |
383 :param initial_repo_list: list of repositories found by scanning methods | 407 :param initial_repo_list: list of repositories found by scanning methods |
384 :param remove_obsolete: check for obsolete entries in database | 408 :param remove_obsolete: check for obsolete entries in database |
385 """ | 409 """ |
386 | 410 from rhodecode.model.repo import RepoModel |
387 sa = meta.Session() | 411 sa = meta.Session |
388 rm = RepoModel() | 412 rm = RepoModel() |
389 user = sa.query(User).filter(User.admin == True).first() | 413 user = sa.query(User).filter(User.admin == True).first() |
414 if user is None: | |
415 raise Exception('Missing administrative account !') | |
390 added = [] | 416 added = [] |
391 # fixup groups paths to new format on the fly | 417 |
392 # TODO: remove this in future | |
393 for g in Group.query().all(): | |
394 g.group_name = g.get_new_name(g.name) | |
395 sa.add(g) | |
396 for name, repo in initial_repo_list.items(): | 418 for name, repo in initial_repo_list.items(): |
397 group = map_groups(name.split(Repository.url_sep())) | 419 group = map_groups(name.split(Repository.url_sep())) |
398 if not rm.get_by_repo_name(name, cache=False): | 420 if not rm.get_by_repo_name(name, cache=False): |
399 log.info('repository %s not found creating default', name) | 421 log.info('repository %s not found creating default' % name) |
400 added.append(name) | 422 added.append(name) |
401 form_data = { | 423 form_data = { |
402 'repo_name': name, | 424 'repo_name': name, |
403 'repo_name_full': name, | 425 'repo_name_full': name, |
404 'repo_type': repo.alias, | 426 'repo_type': repo.alias, |
405 'description': repo.description \ | 427 'description': repo.description \ |
406 if repo.description != 'unknown' else \ | 428 if repo.description != 'unknown' else '%s repository' % name, |
407 '%s repository' % name, | 429 'private': False, |
408 'private': False, | 430 'group_id': getattr(group, 'group_id', None) |
409 'group_id': getattr(group, 'group_id', None) | 431 } |
410 } | |
411 rm.create(form_data, user, just_db=True) | 432 rm.create(form_data, user, just_db=True) |
412 | 433 sa.commit() |
413 removed = [] | 434 removed = [] |
414 if remove_obsolete: | 435 if remove_obsolete: |
415 #remove from database those repositories that are not in the filesystem | 436 #remove from database those repositories that are not in the filesystem |
416 for repo in sa.query(Repository).all(): | 437 for repo in sa.query(Repository).all(): |
417 if repo.repo_name not in initial_repo_list.keys(): | 438 if repo.repo_name not in initial_repo_list.keys(): |
419 sa.delete(repo) | 440 sa.delete(repo) |
420 sa.commit() | 441 sa.commit() |
421 | 442 |
422 return added, removed | 443 return added, removed |
423 | 444 |
424 #set cache regions for beaker so celery can utilise it | 445 |
446 # set cache regions for beaker so celery can utilise it | |
425 def add_cache(settings): | 447 def add_cache(settings): |
426 cache_settings = {'regions': None} | 448 cache_settings = {'regions': None} |
427 for key in settings.keys(): | 449 for key in settings.keys(): |
428 for prefix in ['beaker.cache.', 'cache.']: | 450 for prefix in ['beaker.cache.', 'cache.']: |
429 if key.startswith(prefix): | 451 if key.startswith(prefix): |
453 # TEST FUNCTIONS AND CREATORS | 475 # TEST FUNCTIONS AND CREATORS |
454 #============================================================================== | 476 #============================================================================== |
455 def create_test_index(repo_location, config, full_index): | 477 def create_test_index(repo_location, config, full_index): |
456 """ | 478 """ |
457 Makes default test index | 479 Makes default test index |
458 | 480 |
459 :param config: test config | 481 :param config: test config |
460 :param full_index: | 482 :param full_index: |
461 """ | 483 """ |
462 | 484 |
463 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon | 485 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon |
478 except LockHeld: | 500 except LockHeld: |
479 pass | 501 pass |
480 | 502 |
481 | 503 |
482 def create_test_env(repos_test_path, config): | 504 def create_test_env(repos_test_path, config): |
483 """Makes a fresh database and | 505 """ |
506 Makes a fresh database and | |
484 install test repository into tmp dir | 507 install test repository into tmp dir |
485 """ | 508 """ |
486 from rhodecode.lib.db_manage import DbManage | 509 from rhodecode.lib.db_manage import DbManage |
487 from rhodecode.tests import HG_REPO, GIT_REPO, NEW_HG_REPO, NEW_GIT_REPO, \ | 510 from rhodecode.tests import HG_REPO, TESTS_TMP_PATH |
488 HG_FORK, GIT_FORK, TESTS_TMP_PATH | |
489 import tarfile | |
490 import shutil | |
491 from os.path import abspath | |
492 | 511 |
493 # PART ONE create db | 512 # PART ONE create db |
494 dbconf = config['sqlalchemy.db1.url'] | 513 dbconf = config['sqlalchemy.db1.url'] |
495 log.debug('making test db %s', dbconf) | 514 log.debug('making test db %s' % dbconf) |
496 | 515 |
497 # create test dir if it doesn't exist | 516 # create test dir if it doesn't exist |
498 if not os.path.isdir(repos_test_path): | 517 if not os.path.isdir(repos_test_path): |
499 log.debug('Creating testdir %s' % repos_test_path) | 518 log.debug('Creating testdir %s' % repos_test_path) |
500 os.makedirs(repos_test_path) | 519 os.makedirs(repos_test_path) |
505 dbmanage.create_settings(dbmanage.config_prompt(repos_test_path)) | 524 dbmanage.create_settings(dbmanage.config_prompt(repos_test_path)) |
506 dbmanage.create_default_user() | 525 dbmanage.create_default_user() |
507 dbmanage.admin_prompt() | 526 dbmanage.admin_prompt() |
508 dbmanage.create_permissions() | 527 dbmanage.create_permissions() |
509 dbmanage.populate_default_permissions() | 528 dbmanage.populate_default_permissions() |
510 | 529 Session.commit() |
511 # PART TWO make test repo | 530 # PART TWO make test repo |
512 log.debug('making test vcs repositories') | 531 log.debug('making test vcs repositories') |
513 | 532 |
514 idx_path = config['app_conf']['index_dir'] | 533 idx_path = config['app_conf']['index_dir'] |
515 data_path = config['app_conf']['cache_dir'] | 534 data_path = config['app_conf']['cache_dir'] |
593 from pylons import config as pylonsconfig | 612 from pylons import config as pylonsconfig |
594 | 613 |
595 path_to_ini_file = os.path.realpath(conf) | 614 path_to_ini_file = os.path.realpath(conf) |
596 conf = paste.deploy.appconfig('config:' + path_to_ini_file) | 615 conf = paste.deploy.appconfig('config:' + path_to_ini_file) |
597 pylonsconfig.init_app(conf.global_conf, conf.local_conf) | 616 pylonsconfig.init_app(conf.global_conf, conf.local_conf) |
598 |