##// END OF EJS Templates
Add ini option to controll custom advanced hooks settings
marcink -
r4045:9b4ba12e default
parent child Browse files
Show More
@@ -1,517 +1,522 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # RhodeCode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 pdebug = false
11 11 ################################################################################
12 12 ## Uncomment and replace with the address which should receive ##
13 13 ## any error reports after application crash ##
14 14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 15 ################################################################################
16 16 #email_to = admin@localhost
17 17 #error_email_from = paste_error@localhost
18 18 #app_email_from = rhodecode-noreply@localhost
19 19 #error_message =
20 20 #email_prefix = [RhodeCode]
21 21
22 22 #smtp_server = mail.server.com
23 23 #smtp_username =
24 24 #smtp_password =
25 25 #smtp_port =
26 26 #smtp_use_tls = false
27 27 #smtp_use_ssl = true
28 28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 29 #smtp_auth =
30 30
31 31 [server:main]
32 32 ## PASTE ##
33 33 #use = egg:Paste#http
34 34 ## nr of worker threads to spawn
35 35 #threadpool_workers = 5
36 36 ## max request before thread respawn
37 37 #threadpool_max_requests = 10
38 38 ## option to use threads of process
39 39 #use_threadpool = true
40 40
41 41 ## WAITRESS ##
42 42 use = egg:waitress#main
43 43 ## number of worker threads
44 44 threads = 5
45 45 ## MAX BODY SIZE 100GB
46 46 max_request_body_size = 107374182400
47 47 ## use poll instead of select, fixes fd limits, may not work on old
48 48 ## windows systems.
49 49 #asyncore_use_poll = True
50 50
51 51 ## GUNICORN ##
52 52 #use = egg:gunicorn#main
53 53 ## number of process workers. You must set `instance_id = *` when this option
54 54 ## is set to more than one worker
55 55 #workers = 1
56 56 ## process name
57 57 #proc_name = rhodecode
58 58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 59 ## recommended for bigger setup is using of of other than sync one
60 60 #worker_class = sync
61 61 #max_requests = 5
62 62 ## ammount of time a worker can handle request before it get's killed and
63 63 ## restarted
64 64 #timeout = 3600
65 65
66 66 ## COMMON ##
67 67 host = 0.0.0.0
68 68 port = 5000
69 69
70 70 ## prefix middleware for rc
71 71 #[filter:proxy-prefix]
72 72 #use = egg:PasteDeploy#prefix
73 73 #prefix = /<your-prefix>
74 74
75 75 [app:main]
76 76 use = egg:rhodecode
77 77 ## enable proxy prefix middleware
78 78 #filter-with = proxy-prefix
79 79
80 80 full_stack = true
81 81 static_files = true
82 82 ## Optional Languages
83 83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 84 lang = en
85 85 cache_dir = %(here)s/data
86 86 index_dir = %(here)s/data/index
87 87
88 88 ## perform a full repository scan on each server start, this should be
89 89 ## set to false after first startup, to allow faster server restarts.
90 90 initial_repo_scan = true
91 91
92 92 ## uncomment and set this path to use archive download cache
93 93 #archive_cache_dir = /tmp/tarballcache
94 94
95 95 ## change this to unique ID for security
96 96 app_instance_uuid = rc-production
97 97
98 98 ## cut off limit for large diffs (size in bytes)
99 99 cut_off_limit = 256000
100 100
101 101 ## use cache version of scm repo everywhere
102 102 vcs_full_cache = true
103 103
104 104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 105 force_https = false
106 106
107 107 ## use Strict-Transport-Security headers
108 108 use_htsts = false
109 109
110 110 ## number of commits stats will parse on each iteration
111 111 commit_parse_limit = 25
112 112
113 113 ## use gravatar service to display avatars
114 114 use_gravatar = true
115 115
116 116 ## path to git executable
117 117 git_path = git
118 118
119 119 ## git rev filter option, --all is the default filter, if you need to
120 120 ## hide all refs in changelog switch this to --branches --tags
121 121 git_rev_filter=--all
122 122
123 123 ## RSS feed options
124 124 rss_cut_off_limit = 256000
125 125 rss_items_per_page = 10
126 126 rss_include_diff = false
127 127
128 128 ## options for showing and identifying changesets
129 129 show_sha_length = 12
130 130 show_revision_number = true
131 131
132 132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 133 ## url that does rewrites to _admin/gists/<gistid>.
134 134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 136 gist_alias_url =
137 137
138 138 ## white list of API enabled controllers. This allows to add list of
139 139 ## controllers to which access will be enabled by api_key. eg: to enable
140 140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 143 api_access_controllers_whitelist =
144 144
145 145 ## alternative_gravatar_url allows you to use your own avatar server application
146 146 ## the following parts of the URL will be replaced
147 147 ## {email} user email
148 148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 149 ## {size} size of the image that is expected from the server application
150 150 ## {scheme} http/https from RhodeCode server
151 151 ## {netloc} network location from RhodeCode server
152 152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154 154
155 155
156 156 ## container auth options
157 157 container_auth_enabled = false
158 158 proxypass_auth_enabled = false
159 159
160 160 ## default encoding used to convert from and to unicode
161 161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 162 default_encoding = utf8
163 163
164 164 ## overwrite schema of clone url
165 165 ## available vars:
166 166 ## scheme - http/https
167 167 ## user - current user
168 168 ## pass - password
169 169 ## netloc - network location
170 170 ## path - usually repo_name
171 171
172 172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173 173
174 ## issue tracker RhodeCode (leave blank to disable, absent for default)
174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176 176
177 177 ## issue tracking mapping for commits messages
178 178 ## comment out issue_pat, issue_server, issue_prefix to enable
179 179
180 180 ## pattern to get the issues from commit messages
181 181 ## default one used here is #<numbers> with a regex passive group for `#`
182 182 ## {id} will be all groups matched from this pattern
183 183
184 184 issue_pat = (?:\s*#)(\d+)
185 185
186 186 ## server url to the issue, each {id} will be replaced with match
187 187 ## fetched from the regex and {repo} is replaced with full repository name
188 188 ## including groups {repo_name} is replaced with just name of repo
189 189
190 190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191 191
192 192 ## prefix to add to link to indicate it's an url
193 193 ## #314 will be replaced by <issue_prefix><id>
194 194
195 195 issue_prefix = #
196 196
197 197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 198 ## multiple patterns, to other issues server, wiki or others
199 199 ## below an example how to create a wiki pattern
200 200 # #wiki-some-id -> https://mywiki.com/some-id
201 201
202 202 #issue_pat_wiki = (?:wiki-)(.+)
203 203 #issue_server_link_wiki = https://mywiki.com/{id}
204 204 #issue_prefix_wiki = WIKI-
205 205
206 206
207 207 ## instance-id prefix
208 208 ## a prefix key for this instance used for cache invalidation when running
209 209 ## multiple instances of rhodecode, make sure it's globally unique for
210 210 ## all running rhodecode instances. Leave empty if you don't use it
211 211 instance_id =
212 212
213 213 ## alternative return HTTP header for failed authentication. Default HTTP
214 214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 216 auth_ret_code =
217 217
218 218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 219 ## codes don't break the transactions while 4XX codes do
220 220 lock_ret_code = 423
221 221
222 ## allows to change the repository location in settings page
222 223 allow_repo_location_change = True
223 224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 229 ####################################
225 230 ### CELERY CONFIG ####
226 231 ####################################
227 232 use_celery = false
228 233 broker.host = localhost
229 234 broker.vhost = rabbitmqhost
230 235 broker.port = 5672
231 236 broker.user = rabbitmq
232 237 broker.password = qweqwe
233 238
234 239 celery.imports = rhodecode.lib.celerylib.tasks
235 240
236 241 celery.result.backend = amqp
237 242 celery.result.dburi = amqp://
238 243 celery.result.serialier = json
239 244
240 245 #celery.send.task.error.emails = true
241 246 #celery.amqp.task.result.expires = 18000
242 247
243 248 celeryd.concurrency = 2
244 249 #celeryd.log.file = celeryd.log
245 250 celeryd.log.level = debug
246 251 celeryd.max.tasks.per.child = 1
247 252
248 253 ## tasks will never be sent to the queue, but executed locally instead.
249 254 celery.always.eager = false
250 255
251 256 ####################################
252 257 ### BEAKER CACHE ####
253 258 ####################################
254 259 beaker.cache.data_dir=%(here)s/data/cache/data
255 260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256 261
257 262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258 263
259 264 beaker.cache.super_short_term.type=memory
260 265 beaker.cache.super_short_term.expire=10
261 266 beaker.cache.super_short_term.key_length = 256
262 267
263 268 beaker.cache.short_term.type=memory
264 269 beaker.cache.short_term.expire=60
265 270 beaker.cache.short_term.key_length = 256
266 271
267 272 beaker.cache.long_term.type=memory
268 273 beaker.cache.long_term.expire=36000
269 274 beaker.cache.long_term.key_length = 256
270 275
271 276 beaker.cache.sql_cache_short.type=memory
272 277 beaker.cache.sql_cache_short.expire=10
273 278 beaker.cache.sql_cache_short.key_length = 256
274 279
275 280 beaker.cache.sql_cache_med.type=memory
276 281 beaker.cache.sql_cache_med.expire=360
277 282 beaker.cache.sql_cache_med.key_length = 256
278 283
279 284 beaker.cache.sql_cache_long.type=file
280 285 beaker.cache.sql_cache_long.expire=3600
281 286 beaker.cache.sql_cache_long.key_length = 256
282 287
283 288 ####################################
284 289 ### BEAKER SESSION ####
285 290 ####################################
286 291 ## Type of storage used for the session, current types are
287 292 ## dbm, file, memcached, database, and memory.
288 293 ## The storage uses the Container API
289 294 ## that is also used by the cache system.
290 295
291 296 ## db session ##
292 297 #beaker.session.type = ext:database
293 298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 299 #beaker.session.table_name = db_session
295 300
296 301 ## encrypted cookie client side session, good for many instances ##
297 302 #beaker.session.type = cookie
298 303
299 304 ## file based cookies (default) ##
300 305 #beaker.session.type = file
301 306
302 307 beaker.session.key = rhodecode
303 308 beaker.session.secret = ${app_instance_uuid}
304 309
305 310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 311 ## you must disable beaker.session.secret to use this
307 312 #beaker.session.encrypt_key = <key_for_encryption>
308 313 #beaker.session.validate_key = <validation_key>
309 314
310 315 ## sets session as invalid if it haven't been accessed for given amount of time
311 316 beaker.session.timeout = 2592000
312 317 beaker.session.httponly = true
313 318 #beaker.session.cookie_path = /<your-prefix>
314 319
315 320 ## uncomment for https secure cookie
316 321 beaker.session.secure = false
317 322
318 323 ## auto save the session to not to use .save()
319 324 beaker.session.auto = False
320 325
321 326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 327 #beaker.session.cookie_expires = 3600
323 328
324 329
325 330 ############################
326 331 ## ERROR HANDLING SYSTEMS ##
327 332 ############################
328 333
329 334 ####################
330 335 ### [errormator] ###
331 336 ####################
332 337
333 338 ## Errormator is tailored to work with RhodeCode, see
334 339 ## http://errormator.com for details how to obtain an account
335 340 ## you must install python package `errormator_client` to make it work
336 341
337 342 ## errormator enabled
338 343 errormator = false
339 344
340 345 errormator.server_url = https://api.errormator.com
341 346 errormator.api_key = YOUR_API_KEY
342 347
343 348 ## TWEAK AMOUNT OF INFO SENT HERE
344 349
345 350 ## enables 404 error logging (default False)
346 351 errormator.report_404 = false
347 352
348 353 ## time in seconds after request is considered being slow (default 1)
349 354 errormator.slow_request_time = 1
350 355
351 356 ## record slow requests in application
352 357 ## (needs to be enabled for slow datastore recording and time tracking)
353 358 errormator.slow_requests = true
354 359
355 360 ## enable hooking to application loggers
356 361 # errormator.logging = true
357 362
358 363 ## minimum log level for log capture
359 364 # errormator.logging.level = WARNING
360 365
361 366 ## send logs only from erroneous/slow requests
362 367 ## (saves API quota for intensive logging)
363 368 errormator.logging_on_error = false
364 369
365 370 ## list of additonal keywords that should be grabbed from environ object
366 371 ## can be string with comma separated list of words in lowercase
367 372 ## (by default client will always send following info:
368 373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 374 ## start with HTTP* this list be extended with additional keywords here
370 375 errormator.environ_keys_whitelist =
371 376
372 377
373 378 ## list of keywords that should be blanked from request object
374 379 ## can be string with comma separated list of words in lowercase
375 380 ## (by default client will always blank keys that contain following words
376 381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 382 ## this list be extended with additional keywords set here
378 383 errormator.request_keys_blacklist =
379 384
380 385
381 386 ## list of namespaces that should be ignores when gathering log entries
382 387 ## can be string with comma separated list of namespaces
383 388 ## (by default the client ignores own entries: errormator_client.client)
384 389 errormator.log_namespace_blacklist =
385 390
386 391
387 392 ################
388 393 ### [sentry] ###
389 394 ################
390 395
391 396 ## sentry is a alternative open source error aggregator
392 397 ## you must install python packages `sentry` and `raven` to enable
393 398
394 399 sentry.dsn = YOUR_DNS
395 400 sentry.servers =
396 401 sentry.name =
397 402 sentry.key =
398 403 sentry.public_key =
399 404 sentry.secret_key =
400 405 sentry.project =
401 406 sentry.site =
402 407 sentry.include_paths =
403 408 sentry.exclude_paths =
404 409
405 410
406 411 ################################################################################
407 412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 414 ## execute malicious code after an exception is raised. ##
410 415 ################################################################################
411 416 #set debug = false
412 417
413 418 ##################################
414 419 ### LOGVIEW CONFIG ###
415 420 ##################################
416 421 logview.sqlalchemy = #faa
417 422 logview.pylons.templating = #bfb
418 423 logview.pylons.util = #eee
419 424
420 425 #########################################################
421 426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 427 #########################################################
423 428 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
424 429 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
425 430 sqlalchemy.db1.echo = false
426 431 sqlalchemy.db1.pool_recycle = 3600
427 432 sqlalchemy.db1.convert_unicode = true
428 433
429 434 ################################
430 435 ### LOGGING CONFIGURATION ####
431 436 ################################
432 437 [loggers]
433 438 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
434 439
435 440 [handlers]
436 441 keys = console, console_sql
437 442
438 443 [formatters]
439 444 keys = generic, color_formatter, color_formatter_sql
440 445
441 446 #############
442 447 ## LOGGERS ##
443 448 #############
444 449 [logger_root]
445 450 level = NOTSET
446 451 handlers = console
447 452
448 453 [logger_routes]
449 454 level = DEBUG
450 455 handlers =
451 456 qualname = routes.middleware
452 457 ## "level = DEBUG" logs the route matched and routing variables.
453 458 propagate = 1
454 459
455 460 [logger_beaker]
456 461 level = DEBUG
457 462 handlers =
458 463 qualname = beaker.container
459 464 propagate = 1
460 465
461 466 [logger_templates]
462 467 level = INFO
463 468 handlers =
464 469 qualname = pylons.templating
465 470 propagate = 1
466 471
467 472 [logger_rhodecode]
468 473 level = DEBUG
469 474 handlers =
470 475 qualname = rhodecode
471 476 propagate = 1
472 477
473 478 [logger_sqlalchemy]
474 479 level = INFO
475 480 handlers = console_sql
476 481 qualname = sqlalchemy.engine
477 482 propagate = 0
478 483
479 484 [logger_whoosh_indexer]
480 485 level = DEBUG
481 486 handlers =
482 487 qualname = whoosh_indexer
483 488 propagate = 1
484 489
485 490 ##############
486 491 ## HANDLERS ##
487 492 ##############
488 493
489 494 [handler_console]
490 495 class = StreamHandler
491 496 args = (sys.stderr,)
492 497 level = DEBUG
493 498 formatter = color_formatter
494 499
495 500 [handler_console_sql]
496 501 class = StreamHandler
497 502 args = (sys.stderr,)
498 503 level = DEBUG
499 504 formatter = color_formatter_sql
500 505
501 506 ################
502 507 ## FORMATTERS ##
503 508 ################
504 509
505 510 [formatter_generic]
506 511 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 512 datefmt = %Y-%m-%d %H:%M:%S
508 513
509 514 [formatter_color_formatter]
510 515 class=rhodecode.lib.colored_formatter.ColorFormatter
511 516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
512 517 datefmt = %Y-%m-%d %H:%M:%S
513 518
514 519 [formatter_color_formatter_sql]
515 520 class=rhodecode.lib.colored_formatter.ColorFormatterSql
516 521 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 522 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,517 +1,522 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # RhodeCode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 pdebug = false
11 11 ################################################################################
12 12 ## Uncomment and replace with the address which should receive ##
13 13 ## any error reports after application crash ##
14 14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 15 ################################################################################
16 16 #email_to = admin@localhost
17 17 #error_email_from = paste_error@localhost
18 18 #app_email_from = rhodecode-noreply@localhost
19 19 #error_message =
20 20 #email_prefix = [RhodeCode]
21 21
22 22 #smtp_server = mail.server.com
23 23 #smtp_username =
24 24 #smtp_password =
25 25 #smtp_port =
26 26 #smtp_use_tls = false
27 27 #smtp_use_ssl = true
28 28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 29 #smtp_auth =
30 30
31 31 [server:main]
32 32 ## PASTE ##
33 33 #use = egg:Paste#http
34 34 ## nr of worker threads to spawn
35 35 #threadpool_workers = 5
36 36 ## max request before thread respawn
37 37 #threadpool_max_requests = 10
38 38 ## option to use threads of process
39 39 #use_threadpool = true
40 40
41 41 ## WAITRESS ##
42 42 use = egg:waitress#main
43 43 ## number of worker threads
44 44 threads = 5
45 45 ## MAX BODY SIZE 100GB
46 46 max_request_body_size = 107374182400
47 47 ## use poll instead of select, fixes fd limits, may not work on old
48 48 ## windows systems.
49 49 #asyncore_use_poll = True
50 50
51 51 ## GUNICORN ##
52 52 #use = egg:gunicorn#main
53 53 ## number of process workers. You must set `instance_id = *` when this option
54 54 ## is set to more than one worker
55 55 #workers = 1
56 56 ## process name
57 57 #proc_name = rhodecode
58 58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 59 ## recommended for bigger setup is using of of other than sync one
60 60 #worker_class = sync
61 61 #max_requests = 5
62 62 ## ammount of time a worker can handle request before it get's killed and
63 63 ## restarted
64 64 #timeout = 3600
65 65
66 66 ## COMMON ##
67 67 host = 127.0.0.1
68 68 port = 5000
69 69
70 70 ## prefix middleware for rc
71 71 #[filter:proxy-prefix]
72 72 #use = egg:PasteDeploy#prefix
73 73 #prefix = /<your-prefix>
74 74
75 75 [app:main]
76 76 use = egg:rhodecode
77 77 ## enable proxy prefix middleware
78 78 #filter-with = proxy-prefix
79 79
80 80 full_stack = true
81 81 static_files = true
82 82 ## Optional Languages
83 83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 84 lang = en
85 85 cache_dir = %(here)s/data
86 86 index_dir = %(here)s/data/index
87 87
88 88 ## perform a full repository scan on each server start, this should be
89 89 ## set to false after first startup, to allow faster server restarts.
90 90 initial_repo_scan = true
91 91
92 92 ## uncomment and set this path to use archive download cache
93 93 #archive_cache_dir = /tmp/tarballcache
94 94
95 95 ## change this to unique ID for security
96 96 app_instance_uuid = rc-production
97 97
98 98 ## cut off limit for large diffs (size in bytes)
99 99 cut_off_limit = 256000
100 100
101 101 ## use cache version of scm repo everywhere
102 102 vcs_full_cache = true
103 103
104 104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 105 force_https = false
106 106
107 107 ## use Strict-Transport-Security headers
108 108 use_htsts = false
109 109
110 110 ## number of commits stats will parse on each iteration
111 111 commit_parse_limit = 25
112 112
113 113 ## use gravatar service to display avatars
114 114 use_gravatar = true
115 115
116 116 ## path to git executable
117 117 git_path = git
118 118
119 119 ## git rev filter option, --all is the default filter, if you need to
120 120 ## hide all refs in changelog switch this to --branches --tags
121 121 git_rev_filter=--all
122 122
123 123 ## RSS feed options
124 124 rss_cut_off_limit = 256000
125 125 rss_items_per_page = 10
126 126 rss_include_diff = false
127 127
128 128 ## options for showing and identifying changesets
129 129 show_sha_length = 12
130 130 show_revision_number = true
131 131
132 132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 133 ## url that does rewrites to _admin/gists/<gistid>.
134 134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 136 gist_alias_url =
137 137
138 138 ## white list of API enabled controllers. This allows to add list of
139 139 ## controllers to which access will be enabled by api_key. eg: to enable
140 140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 143 api_access_controllers_whitelist =
144 144
145 145 ## alternative_gravatar_url allows you to use your own avatar server application
146 146 ## the following parts of the URL will be replaced
147 147 ## {email} user email
148 148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 149 ## {size} size of the image that is expected from the server application
150 150 ## {scheme} http/https from RhodeCode server
151 151 ## {netloc} network location from RhodeCode server
152 152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154 154
155 155
156 156 ## container auth options
157 157 container_auth_enabled = false
158 158 proxypass_auth_enabled = false
159 159
160 160 ## default encoding used to convert from and to unicode
161 161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 162 default_encoding = utf8
163 163
164 164 ## overwrite schema of clone url
165 165 ## available vars:
166 166 ## scheme - http/https
167 167 ## user - current user
168 168 ## pass - password
169 169 ## netloc - network location
170 170 ## path - usually repo_name
171 171
172 172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173 173
174 174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176 176
177 177 ## issue tracking mapping for commits messages
178 178 ## comment out issue_pat, issue_server, issue_prefix to enable
179 179
180 180 ## pattern to get the issues from commit messages
181 181 ## default one used here is #<numbers> with a regex passive group for `#`
182 182 ## {id} will be all groups matched from this pattern
183 183
184 184 issue_pat = (?:\s*#)(\d+)
185 185
186 186 ## server url to the issue, each {id} will be replaced with match
187 187 ## fetched from the regex and {repo} is replaced with full repository name
188 188 ## including groups {repo_name} is replaced with just name of repo
189 189
190 190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191 191
192 192 ## prefix to add to link to indicate it's an url
193 193 ## #314 will be replaced by <issue_prefix><id>
194 194
195 195 issue_prefix = #
196 196
197 197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 198 ## multiple patterns, to other issues server, wiki or others
199 199 ## below an example how to create a wiki pattern
200 200 # #wiki-some-id -> https://mywiki.com/some-id
201 201
202 202 #issue_pat_wiki = (?:wiki-)(.+)
203 203 #issue_server_link_wiki = https://mywiki.com/{id}
204 204 #issue_prefix_wiki = WIKI-
205 205
206 206
207 207 ## instance-id prefix
208 208 ## a prefix key for this instance used for cache invalidation when running
209 209 ## multiple instances of rhodecode, make sure it's globally unique for
210 210 ## all running rhodecode instances. Leave empty if you don't use it
211 211 instance_id =
212 212
213 213 ## alternative return HTTP header for failed authentication. Default HTTP
214 214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 216 auth_ret_code =
217 217
218 218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 219 ## codes don't break the transactions while 4XX codes do
220 220 lock_ret_code = 423
221 221
222 ## allows to change the repository location in settings page
222 223 allow_repo_location_change = True
223 224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 229 ####################################
225 230 ### CELERY CONFIG ####
226 231 ####################################
227 232 use_celery = false
228 233 broker.host = localhost
229 234 broker.vhost = rabbitmqhost
230 235 broker.port = 5672
231 236 broker.user = rabbitmq
232 237 broker.password = qweqwe
233 238
234 239 celery.imports = rhodecode.lib.celerylib.tasks
235 240
236 241 celery.result.backend = amqp
237 242 celery.result.dburi = amqp://
238 243 celery.result.serialier = json
239 244
240 245 #celery.send.task.error.emails = true
241 246 #celery.amqp.task.result.expires = 18000
242 247
243 248 celeryd.concurrency = 2
244 249 #celeryd.log.file = celeryd.log
245 250 celeryd.log.level = debug
246 251 celeryd.max.tasks.per.child = 1
247 252
248 253 ## tasks will never be sent to the queue, but executed locally instead.
249 254 celery.always.eager = false
250 255
251 256 ####################################
252 257 ### BEAKER CACHE ####
253 258 ####################################
254 259 beaker.cache.data_dir=%(here)s/data/cache/data
255 260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256 261
257 262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258 263
259 264 beaker.cache.super_short_term.type=memory
260 265 beaker.cache.super_short_term.expire=10
261 266 beaker.cache.super_short_term.key_length = 256
262 267
263 268 beaker.cache.short_term.type=memory
264 269 beaker.cache.short_term.expire=60
265 270 beaker.cache.short_term.key_length = 256
266 271
267 272 beaker.cache.long_term.type=memory
268 273 beaker.cache.long_term.expire=36000
269 274 beaker.cache.long_term.key_length = 256
270 275
271 276 beaker.cache.sql_cache_short.type=memory
272 277 beaker.cache.sql_cache_short.expire=10
273 278 beaker.cache.sql_cache_short.key_length = 256
274 279
275 280 beaker.cache.sql_cache_med.type=memory
276 281 beaker.cache.sql_cache_med.expire=360
277 282 beaker.cache.sql_cache_med.key_length = 256
278 283
279 284 beaker.cache.sql_cache_long.type=file
280 285 beaker.cache.sql_cache_long.expire=3600
281 286 beaker.cache.sql_cache_long.key_length = 256
282 287
283 288 ####################################
284 289 ### BEAKER SESSION ####
285 290 ####################################
286 291 ## Type of storage used for the session, current types are
287 292 ## dbm, file, memcached, database, and memory.
288 293 ## The storage uses the Container API
289 294 ## that is also used by the cache system.
290 295
291 296 ## db session ##
292 297 #beaker.session.type = ext:database
293 298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 299 #beaker.session.table_name = db_session
295 300
296 301 ## encrypted cookie client side session, good for many instances ##
297 302 #beaker.session.type = cookie
298 303
299 304 ## file based cookies (default) ##
300 305 #beaker.session.type = file
301 306
302 307 beaker.session.key = rhodecode
303 308 beaker.session.secret = ${app_instance_uuid}
304 309
305 310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 311 ## you must disable beaker.session.secret to use this
307 312 #beaker.session.encrypt_key = <key_for_encryption>
308 313 #beaker.session.validate_key = <validation_key>
309 314
310 315 ## sets session as invalid if it haven't been accessed for given amount of time
311 316 beaker.session.timeout = 2592000
312 317 beaker.session.httponly = true
313 318 #beaker.session.cookie_path = /<your-prefix>
314 319
315 320 ## uncomment for https secure cookie
316 321 beaker.session.secure = false
317 322
318 323 ## auto save the session to not to use .save()
319 324 beaker.session.auto = False
320 325
321 326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 327 #beaker.session.cookie_expires = 3600
323 328
324 329
325 330 ############################
326 331 ## ERROR HANDLING SYSTEMS ##
327 332 ############################
328 333
329 334 ####################
330 335 ### [errormator] ###
331 336 ####################
332 337
333 338 ## Errormator is tailored to work with RhodeCode, see
334 339 ## http://errormator.com for details how to obtain an account
335 340 ## you must install python package `errormator_client` to make it work
336 341
337 342 ## errormator enabled
338 343 errormator = false
339 344
340 345 errormator.server_url = https://api.errormator.com
341 346 errormator.api_key = YOUR_API_KEY
342 347
343 348 ## TWEAK AMOUNT OF INFO SENT HERE
344 349
345 350 ## enables 404 error logging (default False)
346 351 errormator.report_404 = false
347 352
348 353 ## time in seconds after request is considered being slow (default 1)
349 354 errormator.slow_request_time = 1
350 355
351 356 ## record slow requests in application
352 357 ## (needs to be enabled for slow datastore recording and time tracking)
353 358 errormator.slow_requests = true
354 359
355 360 ## enable hooking to application loggers
356 361 # errormator.logging = true
357 362
358 363 ## minimum log level for log capture
359 364 # errormator.logging.level = WARNING
360 365
361 366 ## send logs only from erroneous/slow requests
362 367 ## (saves API quota for intensive logging)
363 368 errormator.logging_on_error = false
364 369
365 370 ## list of additonal keywords that should be grabbed from environ object
366 371 ## can be string with comma separated list of words in lowercase
367 372 ## (by default client will always send following info:
368 373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 374 ## start with HTTP* this list be extended with additional keywords here
370 375 errormator.environ_keys_whitelist =
371 376
372 377
373 378 ## list of keywords that should be blanked from request object
374 379 ## can be string with comma separated list of words in lowercase
375 380 ## (by default client will always blank keys that contain following words
376 381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 382 ## this list be extended with additional keywords set here
378 383 errormator.request_keys_blacklist =
379 384
380 385
381 386 ## list of namespaces that should be ignores when gathering log entries
382 387 ## can be string with comma separated list of namespaces
383 388 ## (by default the client ignores own entries: errormator_client.client)
384 389 errormator.log_namespace_blacklist =
385 390
386 391
387 392 ################
388 393 ### [sentry] ###
389 394 ################
390 395
391 396 ## sentry is a alternative open source error aggregator
392 397 ## you must install python packages `sentry` and `raven` to enable
393 398
394 399 sentry.dsn = YOUR_DNS
395 400 sentry.servers =
396 401 sentry.name =
397 402 sentry.key =
398 403 sentry.public_key =
399 404 sentry.secret_key =
400 405 sentry.project =
401 406 sentry.site =
402 407 sentry.include_paths =
403 408 sentry.exclude_paths =
404 409
405 410
406 411 ################################################################################
407 412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 414 ## execute malicious code after an exception is raised. ##
410 415 ################################################################################
411 416 set debug = false
412 417
413 418 ##################################
414 419 ### LOGVIEW CONFIG ###
415 420 ##################################
416 421 logview.sqlalchemy = #faa
417 422 logview.pylons.templating = #bfb
418 423 logview.pylons.util = #eee
419 424
420 425 #########################################################
421 426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 427 #########################################################
423 428 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
424 429 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
425 430 sqlalchemy.db1.echo = false
426 431 sqlalchemy.db1.pool_recycle = 3600
427 432 sqlalchemy.db1.convert_unicode = true
428 433
429 434 ################################
430 435 ### LOGGING CONFIGURATION ####
431 436 ################################
432 437 [loggers]
433 438 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
434 439
435 440 [handlers]
436 441 keys = console, console_sql
437 442
438 443 [formatters]
439 444 keys = generic, color_formatter, color_formatter_sql
440 445
441 446 #############
442 447 ## LOGGERS ##
443 448 #############
444 449 [logger_root]
445 450 level = NOTSET
446 451 handlers = console
447 452
448 453 [logger_routes]
449 454 level = DEBUG
450 455 handlers =
451 456 qualname = routes.middleware
452 457 ## "level = DEBUG" logs the route matched and routing variables.
453 458 propagate = 1
454 459
455 460 [logger_beaker]
456 461 level = DEBUG
457 462 handlers =
458 463 qualname = beaker.container
459 464 propagate = 1
460 465
461 466 [logger_templates]
462 467 level = INFO
463 468 handlers =
464 469 qualname = pylons.templating
465 470 propagate = 1
466 471
467 472 [logger_rhodecode]
468 473 level = DEBUG
469 474 handlers =
470 475 qualname = rhodecode
471 476 propagate = 1
472 477
473 478 [logger_sqlalchemy]
474 479 level = INFO
475 480 handlers = console_sql
476 481 qualname = sqlalchemy.engine
477 482 propagate = 0
478 483
479 484 [logger_whoosh_indexer]
480 485 level = DEBUG
481 486 handlers =
482 487 qualname = whoosh_indexer
483 488 propagate = 1
484 489
485 490 ##############
486 491 ## HANDLERS ##
487 492 ##############
488 493
489 494 [handler_console]
490 495 class = StreamHandler
491 496 args = (sys.stderr,)
492 497 level = INFO
493 498 formatter = generic
494 499
495 500 [handler_console_sql]
496 501 class = StreamHandler
497 502 args = (sys.stderr,)
498 503 level = WARN
499 504 formatter = generic
500 505
501 506 ################
502 507 ## FORMATTERS ##
503 508 ################
504 509
505 510 [formatter_generic]
506 511 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 512 datefmt = %Y-%m-%d %H:%M:%S
508 513
509 514 [formatter_color_formatter]
510 515 class=rhodecode.lib.colored_formatter.ColorFormatter
511 516 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
512 517 datefmt = %Y-%m-%d %H:%M:%S
513 518
514 519 [formatter_color_formatter_sql]
515 520 class=rhodecode.lib.colored_formatter.ColorFormatterSql
516 521 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 522 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,545 +1,548 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%text>
3 3 ################################################################################
4 4 ################################################################################
5 5 # RhodeCode - Example config #
6 6 # Built-in functions and variables #
7 7 # The ${here} variable will be replaced with the parent directory of this file #
8 8 # ${uuid()} function will generate a unique hash #
9 9 ################################################################################
10 10 </%text>
11 11 [DEFAULT]
12 12 debug = true
13 13 pdebug = false
14 14 <%text>
15 15 ################################################################################
16 16 ## Uncomment and replace with the address which should receive ##
17 17 ## any error reports after application crash ##
18 18 ## Additionally those settings will be used by RhodeCode mailing system ##
19 19 ################################################################################
20 20 </%text>
21 21 #email_to = admin@localhost
22 22 #error_email_from = paste_error@localhost
23 23 #app_email_from = rhodecode-noreply@localhost
24 24 #error_message =
25 25 #email_prefix = [RhodeCode]
26 26
27 27 #smtp_server = mail.server.com
28 28 #smtp_username =
29 29 #smtp_password =
30 30 #smtp_port =
31 31 #smtp_use_tls = false
32 32 #smtp_use_ssl = true
33 33 <%text>## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)</%text>
34 34 #smtp_auth =
35 35
36 36 [server:main]
37 37 %if http_server == 'paste':
38 38 <%text>## PASTE ##</%text>
39 39 use = egg:Paste#http
40 40 <%text>## nr of worker threads to spawn</%text>
41 41 threadpool_workers = 5
42 42 <%text>## max request before thread respawn</%text>
43 43 threadpool_max_requests = 10
44 44 <%text>## option to use threads of process</%text>
45 45 use_threadpool = true
46 46 %endif
47 47 %if http_server == 'waitress':
48 48 <%text>## WAITRESS ##</%text>
49 49 use = egg:waitress#main
50 50 <%text>## number of worker threads</%text>
51 51 threads = 5
52 52 <%text>## MAX BODY SIZE 100GB</%text>
53 53 max_request_body_size = 107374182400
54 54 <%text>## use poll instead of select, fixes fd limits, may not work on old</%text>
55 55 <%text>## windows systems.</%text>
56 56 #asyncore_use_poll = True
57 57 %endif
58 58 %if http_server == 'gunicorn':
59 59 <%text>## GUNICORN ##</%text>
60 60 use = egg:gunicorn#main
61 61 <%text>## number of process workers. You must set `instance_id = *` when this option</%text>
62 62 <%text>## is set to more than one worker</%text>
63 63 workers = 1
64 64 <%text>## process name</%text>
65 65 proc_name = rhodecode
66 66 <%text>## type of worker class, one of sync, eventlet, gevent, tornado</%text>
67 67 <%text>## recommended for bigger setup is using of of other than sync one</%text>
68 68 worker_class = sync
69 69 max_requests = 1000
70 70 <%text>## ammount of time a worker can handle request before it get's killed and</%text>
71 71 <%text>## restarted</%text>
72 72 timeout = 3600
73 73 %endif
74 74 <%text>## COMMON ##</%text>
75 75 host = ${host}
76 76 port = ${port}
77 77
78 78 <%text>## prefix middleware for rc</%text>
79 79 #[filter:proxy-prefix]
80 80 #use = egg:PasteDeploy#prefix
81 81 #prefix = /<your-prefix>
82 82
83 83 [app:main]
84 84 use = egg:rhodecode
85 85 <%text>## enable proxy prefix middleware</%text>
86 86 #filter-with = proxy-prefix
87 87
88 88 full_stack = true
89 89 static_files = true
90 90 <%text>## Optional Languages</%text>
91 91 <%text>## en, fr, ja, pt_BR, zh_CN, zh_TW, pl, ru</%text>
92 92 lang = ${lang}
93 93 cache_dir = ${here}/data
94 94 index_dir = ${here}/data/index
95 95
96 96 <%text>## perform a full repository scan on each server start, this should be</%text>
97 97 <%text>## set to false after first startup, to allow faster server restarts.</%text>
98 98 initial_repo_scan = false
99 99
100 100 <%text>## uncomment and set this path to use archive download cache</%text>
101 101 archive_cache_dir = ${here}/tarballcache
102 102
103 103 <%text>## change this to unique ID for security</%text>
104 104 app_instance_uuid = ${uuid()}
105 105
106 106 <%text>## cut off limit for large diffs (size in bytes)</%text>
107 107 cut_off_limit = 256000
108 108
109 109 <%text>## use cache version of scm repo everywhere</%text>
110 110 vcs_full_cache = true
111 111
112 112 <%text>## force https in RhodeCode, fixes https redirects, assumes it's always https</%text>
113 113 force_https = false
114 114
115 115 <%text>## use Strict-Transport-Security headers</%text>
116 116 use_htsts = false
117 117
118 118 <%text>## number of commits stats will parse on each iteration</%text>
119 119 commit_parse_limit = 25
120 120
121 121 <%text>## use gravatar service to display avatars</%text>
122 122 use_gravatar = true
123 123
124 124 <%text>## path to git executable</%text>
125 125 git_path = git
126 126
127 127 <%text>## git rev filter option, --all is the default filter, if you need to</%text>
128 128 <%text>## hide all refs in changelog switch this to --branches --tags</%text>
129 129 git_rev_filter=--branches --tags
130 130
131 131 <%text>## RSS feed options</%text>
132 132 rss_cut_off_limit = 256000
133 133 rss_items_per_page = 10
134 134 rss_include_diff = false
135 135
136 136 <%text>## options for showing and identifying changesets</%text>
137 137 show_sha_length = 12
138 138 show_revision_number = true
139 139
140 140 <%text>## gist URL alias, used to create nicer urls for gist. This should be an</%text>
141 141 <%text>## url that does rewrites to _admin/gists/<gistid>.</%text>
142 142 <%text>## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal</%text>
143 143 <%text>## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid></%text>
144 144 gist_alias_url =
145 145
146 146 <%text>## white list of API enabled controllers. This allows to add list of</%text>
147 147 <%text>## controllers to which access will be enabled by api_key. eg: to enable</%text>
148 148 <%text>## api access to raw_files put `FilesController:raw`, to enable access to patches</%text>
149 149 <%text>## add `ChangesetController:changeset_patch`. This list should be "," separated</%text>
150 150 <%text>## Syntax is <ControllerClass>:<function>. Check debug logs for generated names</%text>
151 151 api_access_controllers_whitelist =
152 152
153 153 <%text>## alternative_gravatar_url allows you to use your own avatar server application</%text>
154 154 <%text>## the following parts of the URL will be replaced</%text>
155 155 <%text>## {email} user email</%text>
156 156 <%text>## {md5email} md5 hash of the user email (like at gravatar.com)</%text>
157 157 <%text>## {size} size of the image that is expected from the server application</%text>
158 158 <%text>## {scheme} http/https from RhodeCode server</%text>
159 159 <%text>## {netloc} network location from RhodeCode server</%text>
160 160 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
161 161 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
162 162
163 163
164 164 <%text>## container auth options</%text>
165 165 container_auth_enabled = false
166 166 proxypass_auth_enabled = false
167 167
168 168 <%text>## default encoding used to convert from and to unicode</%text>
169 169 <%text>## can be also a comma seperated list of encoding in case of mixed encodings</%text>
170 170 default_encoding = utf8
171 171
172 172 <%text>## overwrite schema of clone url</%text>
173 173 <%text>## available vars:</%text>
174 174 <%text>## scheme - http/https</%text>
175 175 <%text>## user - current user</%text>
176 176 <%text>## pass - password</%text>
177 177 <%text>## netloc - network location</%text>
178 178 <%text>## path - usually repo_name</%text>
179 179
180 180 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
181 181
182 182 <%text>## issue tracker for RhodeCode (leave blank to disable, absent for default)</%text>
183 183 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
184 184
185 185 <%text>## issue tracking mapping for commits messages</%text>
186 186 <%text>## comment out issue_pat, issue_server, issue_prefix to enable</%text>
187 187
188 188 <%text>## pattern to get the issues from commit messages</%text>
189 189 <%text>## default one used here is #<numbers> with a regex passive group for `#`</%text>
190 190 <%text>## {id} will be all groups matched from this pattern</%text>
191 191
192 192 issue_pat = (?:\s*#)(\d+)
193 193
194 194 <%text>## server url to the issue, each {id} will be replaced with match</%text>
195 195 <%text>## fetched from the regex and {repo} is replaced with full repository name</%text>
196 196 <%text>## including groups {repo_name} is replaced with just name of repo</%text>
197 197
198 198 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
199 199
200 200 <%text>## prefix to add to link to indicate it's an url</%text>
201 201 <%text>## #314 will be replaced by <issue_prefix><id></%text>
202 202
203 203 issue_prefix = #
204 204
205 205 <%text>## issue_pat, issue_server_link, issue_prefix can have suffixes to specify</%text>
206 206 <%text>## multiple patterns, to other issues server, wiki or others</%text>
207 207 <%text>## below an example how to create a wiki pattern</%text>
208 208 <%text>## wiki-some-id -> https://mywiki.com/some-id</%text>
209 209
210 210 #issue_pat_wiki = (?:wiki-)(.+)
211 211 #issue_server_link_wiki = https://mywiki.com/{id}
212 212 #issue_prefix_wiki = WIKI-
213 213
214 214
215 215 <%text>## instance-id prefix</%text>
216 216 <%text>## a prefix key for this instance used for cache invalidation when running</%text>
217 217 <%text>## multiple instances of rhodecode, make sure it's globally unique for</%text>
218 218 <%text>## all running rhodecode instances. Leave empty if you don't use it</%text>
219 219 instance_id =
220 220
221 221 <%text>## alternative return HTTP header for failed authentication. Default HTTP</%text>
222 222 <%text>## response is 401 HTTPUnauthorized. Currently HG clients have troubles with</%text>
223 223 <%text>## handling that. Set this variable to 403 to return HTTPForbidden</%text>
224 224 auth_ret_code =
225 225
226 226 <%text>## locking return code. When repository is locked return this HTTP code. 2XX</%text>
227 227 <%text>## codes don't break the transactions while 4XX codes do</%text>
228 228 lock_ret_code = 423
229 229
230 <%text>## allow chaning the repository store location from web interface</%text>
230 <%text>## allows to change the repository location in settings page</%text>
231 231 allow_repo_location_change = True
232 232
233 <%text>## allows to setup custom hooks in settings page</%text>
234 allow_custom_hooks_settings = True
235
233 236 <%text>
234 237 ####################################
235 238 ### CELERY CONFIG ####
236 239 ####################################
237 240 </%text>
238 241 use_celery = false
239 242 broker.host = localhost
240 243 broker.vhost = rabbitmqhost
241 244 broker.port = 5672
242 245 broker.user = rabbitmq
243 246 broker.password = qweqwe
244 247
245 248 celery.imports = rhodecode.lib.celerylib.tasks
246 249
247 250 celery.result.backend = amqp
248 251 celery.result.dburi = amqp://
249 252 celery.result.serialier = json
250 253
251 254 #celery.send.task.error.emails = true
252 255 #celery.amqp.task.result.expires = 18000
253 256
254 257 celeryd.concurrency = 2
255 258 #celeryd.log.file = celeryd.log
256 259 celeryd.log.level = debug
257 260 celeryd.max.tasks.per.child = 1
258 261
259 262 <%text>## tasks will never be sent to the queue, but executed locally instead.</%text>
260 263 celery.always.eager = false
261 264 <%text>
262 265 ####################################
263 266 ### BEAKER CACHE ####
264 267 ####################################
265 268 </%text>
266 269 beaker.cache.data_dir=${here}/data/cache/data
267 270 beaker.cache.lock_dir=${here}/data/cache/lock
268 271
269 272 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
270 273
271 274 beaker.cache.super_short_term.type=memory
272 275 beaker.cache.super_short_term.expire=10
273 276 beaker.cache.super_short_term.key_length = 256
274 277
275 278 beaker.cache.short_term.type=memory
276 279 beaker.cache.short_term.expire=60
277 280 beaker.cache.short_term.key_length = 256
278 281
279 282 beaker.cache.long_term.type=memory
280 283 beaker.cache.long_term.expire=36000
281 284 beaker.cache.long_term.key_length = 256
282 285
283 286 beaker.cache.sql_cache_short.type=memory
284 287 beaker.cache.sql_cache_short.expire=10
285 288 beaker.cache.sql_cache_short.key_length = 256
286 289
287 290 beaker.cache.sql_cache_med.type=memory
288 291 beaker.cache.sql_cache_med.expire=360
289 292 beaker.cache.sql_cache_med.key_length = 256
290 293
291 294 beaker.cache.sql_cache_long.type=file
292 295 beaker.cache.sql_cache_long.expire=3600
293 296 beaker.cache.sql_cache_long.key_length = 256
294 297 <%text>
295 298 ####################################
296 299 ### BEAKER SESSION ####
297 300 ####################################
298 301 ## Type of storage used for the session, current types are
299 302 ## dbm, file, memcached, database, and memory.
300 303 ## The storage uses the Container API
301 304 ## that is also used by the cache system.
302 305 </%text>
303 306 <%text>## db session ##</%text>
304 307 #beaker.session.type = ext:database
305 308 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
306 309 #beaker.session.table_name = db_session
307 310
308 311 <%text>## encrypted cookie client side session, good for many instances ##</%text>
309 312 #beaker.session.type = cookie
310 313
311 314 <%text>## file based cookies (default) ##</%text>
312 315 #beaker.session.type = file
313 316
314 317 beaker.session.key = rhodecode
315 318 beaker.session.secret = ${uuid()}
316 319
317 320 <%text>## Secure encrypted cookie. Requires AES and AES python libraries</%text>
318 321 <%text>## you must disable beaker.session.secret to use this</%text>
319 322 #beaker.session.encrypt_key = <key_for_encryption>
320 323 #beaker.session.validate_key = <validation_key>
321 324
322 325 <%text>## sets session as invalid if it haven't been accessed for given amount of time</%text>
323 326 beaker.session.timeout = 2592000
324 327 beaker.session.httponly = true
325 328 #beaker.session.cookie_path = /<your-prefix>
326 329
327 330 <%text>## uncomment for https secure cookie</%text>
328 331 beaker.session.secure = false
329 332
330 333 <%text>## auto save the session to not to use .save()</%text>
331 334 beaker.session.auto = False
332 335
333 336 <%text>## default cookie expiration time in seconds `true` expire at browser close ##</%text>
334 337 #beaker.session.cookie_expires = 3600
335 338
336 339 %if error_aggregation_service == 'errormator':
337 340 <%text>
338 341 ############################
339 342 ## ERROR HANDLING SYSTEMS ##
340 343 ############################
341 344
342 345 ####################
343 346 ### [errormator] ###
344 347 ####################
345 348
346 349 ## Errormator is tailored to work with RhodeCode, see
347 350 ## http://errormator.com for details how to obtain an account
348 351 ## you must install python package `errormator_client` to make it work
349 352 </%text>
350 353 <%text>## errormator enabled</%text>
351 354 errormator = false
352 355
353 356 errormator.server_url = https://api.errormator.com
354 357 errormator.api_key = YOUR_API_KEY
355 358
356 359 <%text>## TWEAK AMOUNT OF INFO SENT HERE</%text>
357 360
358 361 <%text>## enables 404 error logging (default False)</%text>
359 362 errormator.report_404 = false
360 363
361 364 <%text>## time in seconds after request is considered being slow (default 1)</%text>
362 365 errormator.slow_request_time = 1
363 366
364 367 <%text>## record slow requests in application</%text>
365 368 <%text>## (needs to be enabled for slow datastore recording and time tracking)</%text>
366 369 errormator.slow_requests = true
367 370
368 371 <%text>## enable hooking to application loggers</%text>
369 372 # errormator.logging = true
370 373
371 374 <%text>## minimum log level for log capture</%text>
372 375 # errormator.logging.level = WARNING
373 376
374 377 <%text>## send logs only from erroneous/slow requests</%text>
375 378 <%text>## (saves API quota for intensive logging)</%text>
376 379 errormator.logging_on_error = false
377 380
378 381 <%text>## list of additonal keywords that should be grabbed from environ object</%text>
379 382 <%text>## can be string with comma separated list of words in lowercase</%text>
380 383 <%text>## (by default client will always send following info:</%text>
381 384 <%text>## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that</%text>
382 385 <%text>## start with HTTP* this list be extended with additional keywords here</%text>
383 386 errormator.environ_keys_whitelist =
384 387
385 388
386 389 <%text>## list of keywords that should be blanked from request object</%text>
387 390 <%text>## can be string with comma separated list of words in lowercase</%text>
388 391 <%text>## (by default client will always blank keys that contain following words</%text>
389 392 <%text>## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'</%text>
390 393 <%text>## this list be extended with additional keywords set here</%text>
391 394 errormator.request_keys_blacklist =
392 395
393 396
394 397 <%text>## list of namespaces that should be ignores when gathering log entries</%text>
395 398 <%text>## can be string with comma separated list of namespaces</%text>
396 399 <%text>## (by default the client ignores own entries: errormator_client.client)</%text>
397 400 errormator.log_namespace_blacklist =
398 401 %elif error_aggregation_service == 'sentry':
399 402 <%text>
400 403 ################
401 404 ### [sentry] ###
402 405 ################
403 406
404 407 ## sentry is a alternative open source error aggregator
405 408 ## you must install python packages `sentry` and `raven` to enable
406 409 </%text>
407 410 sentry.dsn = YOUR_DNS
408 411 sentry.servers =
409 412 sentry.name =
410 413 sentry.key =
411 414 sentry.public_key =
412 415 sentry.secret_key =
413 416 sentry.project =
414 417 sentry.site =
415 418 sentry.include_paths =
416 419 sentry.exclude_paths =
417 420 %endif
418 421 <%text>
419 422 ################################################################################
420 423 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
421 424 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
422 425 ## execute malicious code after an exception is raised. ##
423 426 ################################################################################
424 427 </%text>
425 428 set debug = false
426 429 <%text>
427 430 ##################################
428 431 ### LOGVIEW CONFIG ###
429 432 ##################################
430 433 </%text>
431 434 logview.sqlalchemy = #faa
432 435 logview.pylons.templating = #bfb
433 436 logview.pylons.util = #eee
434 437 <%text>
435 438 #########################################################
436 439 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
437 440 #########################################################
438 441 </%text>
439 442 %if database_engine == 'sqlite':
440 443 # SQLITE [default]
441 444 sqlalchemy.db1.url = sqlite:///${here}/rhodecode.db?timeout=60
442 445 %elif database_engine == 'postgres':
443 446 # POSTGRESQL
444 447 sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
445 448 %elif database_engine == 'mysql':
446 449 # MySQL
447 450 sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
448 451 %endif
449 452 # see sqlalchemy docs for others
450 453
451 454 sqlalchemy.db1.echo = false
452 455 sqlalchemy.db1.pool_recycle = 3600
453 456 sqlalchemy.db1.convert_unicode = true
454 457 <%text>
455 458 ################################
456 459 ### LOGGING CONFIGURATION ####
457 460 ################################
458 461 </%text>
459 462 [loggers]
460 463 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
461 464
462 465 [handlers]
463 466 keys = console, console_sql
464 467
465 468 [formatters]
466 469 keys = generic, color_formatter, color_formatter_sql
467 470 <%text>
468 471 #############
469 472 ## LOGGERS ##
470 473 #############
471 474 </%text>
472 475 [logger_root]
473 476 level = NOTSET
474 477 handlers = console
475 478
476 479 [logger_routes]
477 480 level = DEBUG
478 481 handlers =
479 482 qualname = routes.middleware
480 483 <%text>## "level = DEBUG" logs the route matched and routing variables.</%text>
481 484 propagate = 1
482 485
483 486 [logger_beaker]
484 487 level = DEBUG
485 488 handlers =
486 489 qualname = beaker.container
487 490 propagate = 1
488 491
489 492 [logger_templates]
490 493 level = INFO
491 494 handlers =
492 495 qualname = pylons.templating
493 496 propagate = 1
494 497
495 498 [logger_rhodecode]
496 499 level = DEBUG
497 500 handlers =
498 501 qualname = rhodecode
499 502 propagate = 1
500 503
501 504 [logger_sqlalchemy]
502 505 level = INFO
503 506 handlers = console_sql
504 507 qualname = sqlalchemy.engine
505 508 propagate = 0
506 509
507 510 [logger_whoosh_indexer]
508 511 level = DEBUG
509 512 handlers =
510 513 qualname = whoosh_indexer
511 514 propagate = 1
512 515 <%text>
513 516 ##############
514 517 ## HANDLERS ##
515 518 ##############
516 519 </%text>
517 520 [handler_console]
518 521 class = StreamHandler
519 522 args = (sys.stderr,)
520 523 level = INFO
521 524 formatter = generic
522 525
523 526 [handler_console_sql]
524 527 class = StreamHandler
525 528 args = (sys.stderr,)
526 529 level = WARN
527 530 formatter = generic
528 531 <%text>
529 532 ################
530 533 ## FORMATTERS ##
531 534 ################
532 535 </%text>
533 536 [formatter_generic]
534 537 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
535 538 datefmt = %Y-%m-%d %H:%M:%S
536 539
537 540 [formatter_color_formatter]
538 541 class=rhodecode.lib.colored_formatter.ColorFormatter
539 542 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
540 543 datefmt = %Y-%m-%d %H:%M:%S
541 544
542 545 [formatter_color_formatter_sql]
543 546 class=rhodecode.lib.colored_formatter.ColorFormatterSql
544 547 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
545 548 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,527 +1,532 b''
1 1 ################################################################################
2 2 ################################################################################
3 3 # RhodeCode - Pylons environment configuration #
4 4 # #
5 5 # The %(here)s variable will be replaced with the parent directory of this file#
6 6 ################################################################################
7 7
8 8 [DEFAULT]
9 9 debug = true
10 10 pdebug = false
11 11 ################################################################################
12 12 ## Uncomment and replace with the address which should receive ##
13 13 ## any error reports after application crash ##
14 14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 15 ################################################################################
16 16 #email_to = admin@localhost
17 17 #error_email_from = paste_error@localhost
18 18 #app_email_from = rhodecode-noreply@localhost
19 19 #error_message =
20 20 #email_prefix = [RhodeCode]
21 21
22 22 #smtp_server = mail.server.com
23 23 #smtp_username =
24 24 #smtp_password =
25 25 #smtp_port =
26 26 #smtp_use_tls = false
27 27 #smtp_use_ssl = true
28 28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 29 #smtp_auth =
30 30
31 31 [server:main]
32 32 ## PASTE ##
33 33 #use = egg:Paste#http
34 34 ## nr of worker threads to spawn
35 35 #threadpool_workers = 5
36 36 ## max request before thread respawn
37 37 #threadpool_max_requests = 10
38 38 ## option to use threads of process
39 39 #use_threadpool = true
40 40
41 41 ## WAITRESS ##
42 42 use = egg:waitress#main
43 43 ## number of worker threads
44 44 threads = 5
45 45 ## MAX BODY SIZE 100GB
46 46 max_request_body_size = 107374182400
47 47 ## use poll instead of select, fixes fd limits, may not work on old
48 48 ## windows systems.
49 49 #asyncore_use_poll = True
50 50
51 51 ## GUNICORN ##
52 52 #use = egg:gunicorn#main
53 53 ## number of process workers. You must set `instance_id = *` when this option
54 54 ## is set to more than one worker
55 55 #workers = 1
56 56 ## process name
57 57 #proc_name = rhodecode
58 58 ## type of worker class, one of sync, eventlet, gevent, tornado
59 59 ## recommended for bigger setup is using of of other than sync one
60 60 #worker_class = sync
61 61 #max_requests = 5
62 62 ## ammount of time a worker can handle request before it get's killed and
63 63 ## restarted
64 64 #timeout = 3600
65 65
66 66 ## COMMON ##
67 67 host = 127.0.0.1
68 68 port = 5000
69 69
70 70 ## prefix middleware for rc
71 71 #[filter:proxy-prefix]
72 72 #use = egg:PasteDeploy#prefix
73 73 #prefix = /<your-prefix>
74 74
75 75 [app:main]
76 76 use = egg:rhodecode
77 77 ## enable proxy prefix middleware
78 78 #filter-with = proxy-prefix
79 79
80 80 full_stack = true
81 81 static_files = true
82 82 ## Optional Languages
83 83 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
84 84 lang = en
85 85 cache_dir = %(here)s/data
86 86 index_dir = %(here)s/data/index
87 87
88 88 ## perform a full repository scan on each server start, this should be
89 89 ## set to false after first startup, to allow faster server restarts.
90 90 initial_repo_scan = true
91 91
92 92 ## uncomment and set this path to use archive download cache
93 93 #archive_cache_dir = /tmp/tarballcache
94 94
95 95 ## change this to unique ID for security
96 96 app_instance_uuid = ${app_instance_uuid}
97 97
98 98 ## cut off limit for large diffs (size in bytes)
99 99 cut_off_limit = 256000
100 100
101 101 ## use cache version of scm repo everywhere
102 102 vcs_full_cache = true
103 103
104 104 ## force https in RhodeCode, fixes https redirects, assumes it's always https
105 105 force_https = false
106 106
107 107 ## use Strict-Transport-Security headers
108 108 use_htsts = false
109 109
110 110 ## number of commits stats will parse on each iteration
111 111 commit_parse_limit = 25
112 112
113 113 ## use gravatar service to display avatars
114 114 use_gravatar = true
115 115
116 116 ## path to git executable
117 117 git_path = git
118 118
119 119 ## git rev filter option, --all is the default filter, if you need to
120 120 ## hide all refs in changelog switch this to --branches --tags
121 121 git_rev_filter=--all
122 122
123 123 ## RSS feed options
124 124 rss_cut_off_limit = 256000
125 125 rss_items_per_page = 10
126 126 rss_include_diff = false
127 127
128 128 ## options for showing and identifying changesets
129 129 show_sha_length = 12
130 130 show_revision_number = true
131 131
132 132 ## gist URL alias, used to create nicer urls for gist. This should be an
133 133 ## url that does rewrites to _admin/gists/<gistid>.
134 134 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
135 135 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
136 136 gist_alias_url =
137 137
138 138 ## white list of API enabled controllers. This allows to add list of
139 139 ## controllers to which access will be enabled by api_key. eg: to enable
140 140 ## api access to raw_files put `FilesController:raw`, to enable access to patches
141 141 ## add `ChangesetController:changeset_patch`. This list should be "," separated
142 142 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
143 143 api_access_controllers_whitelist =
144 144
145 145 ## alternative_gravatar_url allows you to use your own avatar server application
146 146 ## the following parts of the URL will be replaced
147 147 ## {email} user email
148 148 ## {md5email} md5 hash of the user email (like at gravatar.com)
149 149 ## {size} size of the image that is expected from the server application
150 150 ## {scheme} http/https from RhodeCode server
151 151 ## {netloc} network location from RhodeCode server
152 152 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
153 153 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
154 154
155 155
156 156 ## container auth options
157 157 container_auth_enabled = false
158 158 proxypass_auth_enabled = false
159 159
160 160 ## default encoding used to convert from and to unicode
161 161 ## can be also a comma seperated list of encoding in case of mixed encodings
162 162 default_encoding = utf8
163 163
164 164 ## overwrite schema of clone url
165 165 ## available vars:
166 166 ## scheme - http/https
167 167 ## user - current user
168 168 ## pass - password
169 169 ## netloc - network location
170 170 ## path - usually repo_name
171 171
172 172 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
173 173
174 174 ## issue tracker for RhodeCode (leave blank to disable, absent for default)
175 175 #bugtracker = http://bitbucket.org/marcinkuzminski/rhodecode/issues
176 176
177 177 ## issue tracking mapping for commits messages
178 178 ## comment out issue_pat, issue_server, issue_prefix to enable
179 179
180 180 ## pattern to get the issues from commit messages
181 181 ## default one used here is #<numbers> with a regex passive group for `#`
182 182 ## {id} will be all groups matched from this pattern
183 183
184 184 issue_pat = (?:\s*#)(\d+)
185 185
186 186 ## server url to the issue, each {id} will be replaced with match
187 187 ## fetched from the regex and {repo} is replaced with full repository name
188 188 ## including groups {repo_name} is replaced with just name of repo
189 189
190 190 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
191 191
192 192 ## prefix to add to link to indicate it's an url
193 193 ## #314 will be replaced by <issue_prefix><id>
194 194
195 195 issue_prefix = #
196 196
197 197 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
198 198 ## multiple patterns, to other issues server, wiki or others
199 199 ## below an example how to create a wiki pattern
200 200 # #wiki-some-id -> https://mywiki.com/some-id
201 201
202 202 #issue_pat_wiki = (?:wiki-)(.+)
203 203 #issue_server_link_wiki = https://mywiki.com/{id}
204 204 #issue_prefix_wiki = WIKI-
205 205
206 206
207 207 ## instance-id prefix
208 208 ## a prefix key for this instance used for cache invalidation when running
209 209 ## multiple instances of rhodecode, make sure it's globally unique for
210 210 ## all running rhodecode instances. Leave empty if you don't use it
211 211 instance_id =
212 212
213 213 ## alternative return HTTP header for failed authentication. Default HTTP
214 214 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
215 215 ## handling that. Set this variable to 403 to return HTTPForbidden
216 216 auth_ret_code =
217 217
218 218 ## locking return code. When repository is locked return this HTTP code. 2XX
219 219 ## codes don't break the transactions while 4XX codes do
220 220 lock_ret_code = 423
221 221
222 ## allows to change the repository location in settings page
222 223 allow_repo_location_change = True
223 224
225 ## allows to setup custom hooks in settings page
226 allow_custom_hooks_settings = True
227
228
224 229 ####################################
225 230 ### CELERY CONFIG ####
226 231 ####################################
227 232 use_celery = false
228 233 broker.host = localhost
229 234 broker.vhost = rabbitmqhost
230 235 broker.port = 5672
231 236 broker.user = rabbitmq
232 237 broker.password = qweqwe
233 238
234 239 celery.imports = rhodecode.lib.celerylib.tasks
235 240
236 241 celery.result.backend = amqp
237 242 celery.result.dburi = amqp://
238 243 celery.result.serialier = json
239 244
240 245 #celery.send.task.error.emails = true
241 246 #celery.amqp.task.result.expires = 18000
242 247
243 248 celeryd.concurrency = 2
244 249 #celeryd.log.file = celeryd.log
245 250 celeryd.log.level = debug
246 251 celeryd.max.tasks.per.child = 1
247 252
248 253 ## tasks will never be sent to the queue, but executed locally instead.
249 254 celery.always.eager = false
250 255
251 256 ####################################
252 257 ### BEAKER CACHE ####
253 258 ####################################
254 259 beaker.cache.data_dir=%(here)s/data/cache/data
255 260 beaker.cache.lock_dir=%(here)s/data/cache/lock
256 261
257 262 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
258 263
259 264 beaker.cache.super_short_term.type=memory
260 265 beaker.cache.super_short_term.expire=10
261 266 beaker.cache.super_short_term.key_length = 256
262 267
263 268 beaker.cache.short_term.type=memory
264 269 beaker.cache.short_term.expire=60
265 270 beaker.cache.short_term.key_length = 256
266 271
267 272 beaker.cache.long_term.type=memory
268 273 beaker.cache.long_term.expire=36000
269 274 beaker.cache.long_term.key_length = 256
270 275
271 276 beaker.cache.sql_cache_short.type=memory
272 277 beaker.cache.sql_cache_short.expire=10
273 278 beaker.cache.sql_cache_short.key_length = 256
274 279
275 280 beaker.cache.sql_cache_med.type=memory
276 281 beaker.cache.sql_cache_med.expire=360
277 282 beaker.cache.sql_cache_med.key_length = 256
278 283
279 284 beaker.cache.sql_cache_long.type=file
280 285 beaker.cache.sql_cache_long.expire=3600
281 286 beaker.cache.sql_cache_long.key_length = 256
282 287
283 288 ####################################
284 289 ### BEAKER SESSION ####
285 290 ####################################
286 291 ## Type of storage used for the session, current types are
287 292 ## dbm, file, memcached, database, and memory.
288 293 ## The storage uses the Container API
289 294 ## that is also used by the cache system.
290 295
291 296 ## db session ##
292 297 #beaker.session.type = ext:database
293 298 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
294 299 #beaker.session.table_name = db_session
295 300
296 301 ## encrypted cookie client side session, good for many instances ##
297 302 #beaker.session.type = cookie
298 303
299 304 ## file based cookies (default) ##
300 305 #beaker.session.type = file
301 306
302 307 beaker.session.key = rhodecode
303 308 beaker.session.secret = ${app_instance_uuid}
304 309
305 310 ## Secure encrypted cookie. Requires AES and AES python libraries
306 311 ## you must disable beaker.session.secret to use this
307 312 #beaker.session.encrypt_key = <key_for_encryption>
308 313 #beaker.session.validate_key = <validation_key>
309 314
310 315 ## sets session as invalid if it haven't been accessed for given amount of time
311 316 beaker.session.timeout = 2592000
312 317 beaker.session.httponly = true
313 318 #beaker.session.cookie_path = /<your-prefix>
314 319
315 320 ## uncomment for https secure cookie
316 321 beaker.session.secure = false
317 322
318 323 ## auto save the session to not to use .save()
319 324 beaker.session.auto = False
320 325
321 326 ## default cookie expiration time in seconds `true` expire at browser close ##
322 327 #beaker.session.cookie_expires = 3600
323 328
324 329
325 330 ############################
326 331 ## ERROR HANDLING SYSTEMS ##
327 332 ############################
328 333
329 334 ####################
330 335 ### [errormator] ###
331 336 ####################
332 337
333 338 ## Errormator is tailored to work with RhodeCode, see
334 339 ## http://errormator.com for details how to obtain an account
335 340 ## you must install python package `errormator_client` to make it work
336 341
337 342 ## errormator enabled
338 343 errormator = false
339 344
340 345 errormator.server_url = https://api.errormator.com
341 346 errormator.api_key = YOUR_API_KEY
342 347
343 348 ## TWEAK AMOUNT OF INFO SENT HERE
344 349
345 350 ## enables 404 error logging (default False)
346 351 errormator.report_404 = false
347 352
348 353 ## time in seconds after request is considered being slow (default 1)
349 354 errormator.slow_request_time = 1
350 355
351 356 ## record slow requests in application
352 357 ## (needs to be enabled for slow datastore recording and time tracking)
353 358 errormator.slow_requests = true
354 359
355 360 ## enable hooking to application loggers
356 361 # errormator.logging = true
357 362
358 363 ## minimum log level for log capture
359 364 # errormator.logging.level = WARNING
360 365
361 366 ## send logs only from erroneous/slow requests
362 367 ## (saves API quota for intensive logging)
363 368 errormator.logging_on_error = false
364 369
365 370 ## list of additonal keywords that should be grabbed from environ object
366 371 ## can be string with comma separated list of words in lowercase
367 372 ## (by default client will always send following info:
368 373 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
369 374 ## start with HTTP* this list be extended with additional keywords here
370 375 errormator.environ_keys_whitelist =
371 376
372 377
373 378 ## list of keywords that should be blanked from request object
374 379 ## can be string with comma separated list of words in lowercase
375 380 ## (by default client will always blank keys that contain following words
376 381 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
377 382 ## this list be extended with additional keywords set here
378 383 errormator.request_keys_blacklist =
379 384
380 385
381 386 ## list of namespaces that should be ignores when gathering log entries
382 387 ## can be string with comma separated list of namespaces
383 388 ## (by default the client ignores own entries: errormator_client.client)
384 389 errormator.log_namespace_blacklist =
385 390
386 391
387 392 ################
388 393 ### [sentry] ###
389 394 ################
390 395
391 396 ## sentry is a alternative open source error aggregator
392 397 ## you must install python packages `sentry` and `raven` to enable
393 398
394 399 sentry.dsn = YOUR_DNS
395 400 sentry.servers =
396 401 sentry.name =
397 402 sentry.key =
398 403 sentry.public_key =
399 404 sentry.secret_key =
400 405 sentry.project =
401 406 sentry.site =
402 407 sentry.include_paths =
403 408 sentry.exclude_paths =
404 409
405 410
406 411 ################################################################################
407 412 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
408 413 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
409 414 ## execute malicious code after an exception is raised. ##
410 415 ################################################################################
411 416 set debug = false
412 417
413 418 ##################################
414 419 ### LOGVIEW CONFIG ###
415 420 ##################################
416 421 logview.sqlalchemy = #faa
417 422 logview.pylons.templating = #bfb
418 423 logview.pylons.util = #eee
419 424
420 425 #########################################################
421 426 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
422 427 #########################################################
423 428
424 429 # SQLITE [default]
425 430 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
426 431
427 432 # POSTGRESQL
428 433 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
429 434
430 435 # MySQL
431 436 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
432 437
433 438 # see sqlalchemy docs for others
434 439
435 440 sqlalchemy.db1.echo = false
436 441 sqlalchemy.db1.pool_recycle = 3600
437 442 sqlalchemy.db1.convert_unicode = true
438 443
439 444 ################################
440 445 ### LOGGING CONFIGURATION ####
441 446 ################################
442 447 [loggers]
443 448 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
444 449
445 450 [handlers]
446 451 keys = console, console_sql
447 452
448 453 [formatters]
449 454 keys = generic, color_formatter, color_formatter_sql
450 455
451 456 #############
452 457 ## LOGGERS ##
453 458 #############
454 459 [logger_root]
455 460 level = NOTSET
456 461 handlers = console
457 462
458 463 [logger_routes]
459 464 level = DEBUG
460 465 handlers =
461 466 qualname = routes.middleware
462 467 ## "level = DEBUG" logs the route matched and routing variables.
463 468 propagate = 1
464 469
465 470 [logger_beaker]
466 471 level = DEBUG
467 472 handlers =
468 473 qualname = beaker.container
469 474 propagate = 1
470 475
471 476 [logger_templates]
472 477 level = INFO
473 478 handlers =
474 479 qualname = pylons.templating
475 480 propagate = 1
476 481
477 482 [logger_rhodecode]
478 483 level = DEBUG
479 484 handlers =
480 485 qualname = rhodecode
481 486 propagate = 1
482 487
483 488 [logger_sqlalchemy]
484 489 level = INFO
485 490 handlers = console_sql
486 491 qualname = sqlalchemy.engine
487 492 propagate = 0
488 493
489 494 [logger_whoosh_indexer]
490 495 level = DEBUG
491 496 handlers =
492 497 qualname = whoosh_indexer
493 498 propagate = 1
494 499
495 500 ##############
496 501 ## HANDLERS ##
497 502 ##############
498 503
499 504 [handler_console]
500 505 class = StreamHandler
501 506 args = (sys.stderr,)
502 507 level = INFO
503 508 formatter = generic
504 509
505 510 [handler_console_sql]
506 511 class = StreamHandler
507 512 args = (sys.stderr,)
508 513 level = WARN
509 514 formatter = generic
510 515
511 516 ################
512 517 ## FORMATTERS ##
513 518 ################
514 519
515 520 [formatter_generic]
516 521 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 522 datefmt = %Y-%m-%d %H:%M:%S
518 523
519 524 [formatter_color_formatter]
520 525 class=rhodecode.lib.colored_formatter.ColorFormatter
521 526 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
522 527 datefmt = %Y-%m-%d %H:%M:%S
523 528
524 529 [formatter_color_formatter_sql]
525 530 class=rhodecode.lib.colored_formatter.ColorFormatterSql
526 531 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
527 532 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,523 +1,524 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 rhodecode.controllers.admin.settings
4 4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 5
6 6 settings controller for rhodecode admin
7 7
8 8 :created_on: Jul 14, 2010
9 9 :author: marcink
10 10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 11 :license: GPLv3, see COPYING for more details.
12 12 """
13 13 # This program is free software: you can redistribute it and/or modify
14 14 # it under the terms of the GNU General Public License as published by
15 15 # the Free Software Foundation, either version 3 of the License, or
16 16 # (at your option) any later version.
17 17 #
18 18 # This program is distributed in the hope that it will be useful,
19 19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 21 # GNU General Public License for more details.
22 22 #
23 23 # You should have received a copy of the GNU General Public License
24 24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 25
26 26 import logging
27 27 import traceback
28 28 import formencode
29 29 import pkg_resources
30 30 import platform
31 31
32 32 from sqlalchemy import func
33 33 from formencode import htmlfill
34 34 from pylons import request, session, tmpl_context as c, url, config
35 35 from pylons.controllers.util import abort, redirect
36 36 from pylons.i18n.translation import _
37 37
38 38 from rhodecode.lib import helpers as h
39 39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, \
40 40 HasPermissionAnyDecorator, NotAnonymous, HasPermissionAny,\
41 41 HasReposGroupPermissionAll, HasReposGroupPermissionAny, AuthUser
42 42 from rhodecode.lib.base import BaseController, render
43 43 from rhodecode.lib.celerylib import tasks, run_task
44 44 from rhodecode.lib.utils import repo2db_mapper, set_rhodecode_config, \
45 45 check_git_version
46 46 from rhodecode.model.db import RhodeCodeUi, Repository, RepoGroup, \
47 47 RhodeCodeSetting, PullRequest, PullRequestReviewers
48 48 from rhodecode.model.forms import UserForm, ApplicationSettingsForm, \
49 49 ApplicationUiSettingsForm, ApplicationVisualisationForm
50 50 from rhodecode.model.scm import ScmModel, RepoGroupList
51 51 from rhodecode.model.user import UserModel
52 52 from rhodecode.model.repo import RepoModel
53 53 from rhodecode.model.db import User
54 54 from rhodecode.model.notification import EmailNotificationModel
55 55 from rhodecode.model.meta import Session
56 56 from rhodecode.lib.utils2 import str2bool, safe_unicode
57 57 from rhodecode.lib.compat import json
58 58 log = logging.getLogger(__name__)
59 59
60 60
61 61 class SettingsController(BaseController):
62 62 """REST Controller styled on the Atom Publishing Protocol"""
63 63 # To properly map this controller, ensure your config/routing.py
64 64 # file has a resource setup:
65 65 # map.resource('setting', 'settings', controller='admin/settings',
66 66 # path_prefix='/admin', name_prefix='admin_')
67 67
68 68 @LoginRequired()
69 69 def __before__(self):
70 70 super(SettingsController, self).__before__()
71 71 c.modules = sorted([(p.project_name, p.version)
72 72 for p in pkg_resources.working_set]
73 73 + [('git', check_git_version())],
74 74 key=lambda k: k[0].lower())
75 75 c.py_version = platform.python_version()
76 76 c.platform = platform.platform()
77 77
78 78 @HasPermissionAllDecorator('hg.admin')
79 79 def index(self, format='html'):
80 80 """GET /admin/settings: All items in the collection"""
81 81 # url('admin_settings')
82 82
83 83 defaults = RhodeCodeSetting.get_app_settings()
84 84 defaults.update(self._get_hg_ui_settings())
85 85
86 86 return htmlfill.render(
87 87 render('admin/settings/settings.html'),
88 88 defaults=defaults,
89 89 encoding="UTF-8",
90 90 force_defaults=False
91 91 )
92 92
93 93 @HasPermissionAllDecorator('hg.admin')
94 94 def create(self):
95 95 """POST /admin/settings: Create a new item"""
96 96 # url('admin_settings')
97 97
98 98 @HasPermissionAllDecorator('hg.admin')
99 99 def new(self, format='html'):
100 100 """GET /admin/settings/new: Form to create a new item"""
101 101 # url('admin_new_setting')
102 102
103 103 @HasPermissionAllDecorator('hg.admin')
104 104 def update(self, setting_id):
105 105 """PUT /admin/settings/setting_id: Update an existing item"""
106 106 # Forms posted to this method should contain a hidden field:
107 107 # <input type="hidden" name="_method" value="PUT" />
108 108 # Or using helpers:
109 109 # h.form(url('admin_setting', setting_id=ID),
110 110 # method='put')
111 111 # url('admin_setting', setting_id=ID)
112 112
113 113 if setting_id == 'mapping':
114 114 rm_obsolete = request.POST.get('destroy', False)
115 115 invalidate_cache = request.POST.get('invalidate', False)
116 116 log.debug('rescanning repo location with destroy obsolete=%s'
117 117 % (rm_obsolete,))
118 118
119 119 if invalidate_cache:
120 120 log.debug('invalidating all repositories cache')
121 121 for repo in Repository.get_all():
122 122 ScmModel().mark_for_invalidation(repo.repo_name)
123 123
124 124 filesystem_repos = ScmModel().repo_scan()
125 125 added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
126 126 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
127 127 h.flash(_('Repositories successfully '
128 128 'rescanned added: %s ; removed: %s') %
129 129 (_repr(added), _repr(removed)),
130 130 category='success')
131 131
132 132 if setting_id == 'whoosh':
133 133 repo_location = self._get_hg_ui_settings()['paths_root_path']
134 134 full_index = request.POST.get('full_index', False)
135 135 run_task(tasks.whoosh_index, repo_location, full_index)
136 136 h.flash(_('Whoosh reindex task scheduled'), category='success')
137 137
138 138 if setting_id == 'global':
139 139
140 140 application_form = ApplicationSettingsForm()()
141 141 try:
142 142 form_result = application_form.to_python(dict(request.POST))
143 143 except formencode.Invalid, errors:
144 144 return htmlfill.render(
145 145 render('admin/settings/settings.html'),
146 146 defaults=errors.value,
147 147 errors=errors.error_dict or {},
148 148 prefix_error=False,
149 149 encoding="UTF-8"
150 150 )
151 151
152 152 try:
153 153 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
154 154 sett1.app_settings_value = form_result['rhodecode_title']
155 155 Session().add(sett1)
156 156
157 157 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
158 158 sett2.app_settings_value = form_result['rhodecode_realm']
159 159 Session().add(sett2)
160 160
161 161 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
162 162 sett3.app_settings_value = form_result['rhodecode_ga_code']
163 163 Session().add(sett3)
164 164
165 165 Session().commit()
166 166 set_rhodecode_config(config)
167 167 h.flash(_('Updated application settings'), category='success')
168 168
169 169 except Exception:
170 170 log.error(traceback.format_exc())
171 171 h.flash(_('Error occurred during updating '
172 172 'application settings'),
173 173 category='error')
174 174
175 175 if setting_id == 'visual':
176 176
177 177 application_form = ApplicationVisualisationForm()()
178 178 try:
179 179 form_result = application_form.to_python(dict(request.POST))
180 180 except formencode.Invalid, errors:
181 181 return htmlfill.render(
182 182 render('admin/settings/settings.html'),
183 183 defaults=errors.value,
184 184 errors=errors.error_dict or {},
185 185 prefix_error=False,
186 186 encoding="UTF-8"
187 187 )
188 188
189 189 try:
190 190 #TODO: rewrite this to something less ugly
191 191 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
192 192 sett1.app_settings_value = \
193 193 form_result['rhodecode_show_public_icon']
194 194 Session().add(sett1)
195 195
196 196 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
197 197 sett2.app_settings_value = \
198 198 form_result['rhodecode_show_private_icon']
199 199 Session().add(sett2)
200 200
201 201 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
202 202 sett3.app_settings_value = \
203 203 form_result['rhodecode_stylify_metatags']
204 204 Session().add(sett3)
205 205
206 206 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
207 207 sett4.app_settings_value = \
208 208 form_result['rhodecode_repository_fields']
209 209 Session().add(sett4)
210 210
211 211 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
212 212 sett5.app_settings_value = \
213 213 form_result['rhodecode_dashboard_items']
214 214 Session().add(sett5)
215 215
216 216 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
217 217 sett6.app_settings_value = \
218 218 form_result['rhodecode_show_version']
219 219 Session().add(sett6)
220 220
221 221 Session().commit()
222 222 set_rhodecode_config(config)
223 223 h.flash(_('Updated visualisation settings'),
224 224 category='success')
225 225
226 226 except Exception:
227 227 log.error(traceback.format_exc())
228 228 h.flash(_('Error occurred during updating '
229 229 'visualisation settings'),
230 230 category='error')
231 231
232 232 if setting_id == 'vcs':
233 233 application_form = ApplicationUiSettingsForm()()
234 234 try:
235 235 form_result = application_form.to_python(dict(request.POST))
236 236 except formencode.Invalid, errors:
237 237 return htmlfill.render(
238 238 render('admin/settings/settings.html'),
239 239 defaults=errors.value,
240 240 errors=errors.error_dict or {},
241 241 prefix_error=False,
242 242 encoding="UTF-8"
243 243 )
244 244
245 245 try:
246 246 sett = RhodeCodeUi.get_by_key('push_ssl')
247 247 sett.ui_value = form_result['web_push_ssl']
248 248 Session().add(sett)
249 249 if c.visual.allow_repo_location_change:
250 250 sett = RhodeCodeUi.get_by_key('/')
251 251 sett.ui_value = form_result['paths_root_path']
252 252 Session().add(sett)
253 253
254 254 #HOOKS
255 255 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
256 256 sett.ui_active = form_result['hooks_changegroup_update']
257 257 Session().add(sett)
258 258
259 259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
260 260 sett.ui_active = form_result['hooks_changegroup_repo_size']
261 261 Session().add(sett)
262 262
263 263 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
264 264 sett.ui_active = form_result['hooks_changegroup_push_logger']
265 265 Session().add(sett)
266 266
267 267 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
268 268 sett.ui_active = form_result['hooks_outgoing_pull_logger']
269 269
270 270 Session().add(sett)
271 271
272 272 ## EXTENSIONS
273 273 sett = RhodeCodeUi.get_by_key('largefiles')
274 274 if not sett:
275 275 #make one if it's not there !
276 276 sett = RhodeCodeUi()
277 277 sett.ui_key = 'largefiles'
278 278 sett.ui_section = 'extensions'
279 279 sett.ui_active = form_result['extensions_largefiles']
280 280 Session().add(sett)
281 281
282 282 sett = RhodeCodeUi.get_by_key('hgsubversion')
283 283 if not sett:
284 284 #make one if it's not there !
285 285 sett = RhodeCodeUi()
286 286 sett.ui_key = 'hgsubversion'
287 287 sett.ui_section = 'extensions'
288 288
289 289 sett.ui_active = form_result['extensions_hgsubversion']
290 290 Session().add(sett)
291 291
292 292 # sett = RhodeCodeUi.get_by_key('hggit')
293 293 # if not sett:
294 294 # #make one if it's not there !
295 295 # sett = RhodeCodeUi()
296 296 # sett.ui_key = 'hggit'
297 297 # sett.ui_section = 'extensions'
298 298 #
299 299 # sett.ui_active = form_result['extensions_hggit']
300 300 # Session().add(sett)
301 301
302 302 Session().commit()
303 303
304 304 h.flash(_('Updated VCS settings'), category='success')
305 305
306 306 except Exception:
307 307 log.error(traceback.format_exc())
308 308 h.flash(_('Error occurred during updating '
309 309 'application settings'), category='error')
310 310
311 311 if setting_id == 'hooks':
312 ui_key = request.POST.get('new_hook_ui_key')
313 ui_value = request.POST.get('new_hook_ui_value')
314 try:
312 if c.visual.allow_custom_hooks_settings:
313 ui_key = request.POST.get('new_hook_ui_key')
314 ui_value = request.POST.get('new_hook_ui_value')
315 try:
315 316
316 if ui_value and ui_key:
317 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
318 h.flash(_('Added new hook'),
319 category='success')
317 if ui_value and ui_key:
318 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
319 h.flash(_('Added new hook'),
320 category='success')
320 321
321 # check for edits
322 update = False
323 _d = request.POST.dict_of_lists()
324 for k, v in zip(_d.get('hook_ui_key', []),
325 _d.get('hook_ui_value_new', [])):
326 RhodeCodeUi.create_or_update_hook(k, v)
327 update = True
322 # check for edits
323 update = False
324 _d = request.POST.dict_of_lists()
325 for k, v in zip(_d.get('hook_ui_key', []),
326 _d.get('hook_ui_value_new', [])):
327 RhodeCodeUi.create_or_update_hook(k, v)
328 update = True
328 329
329 if update:
330 h.flash(_('Updated hooks'), category='success')
331 Session().commit()
332 except Exception:
333 log.error(traceback.format_exc())
334 h.flash(_('Error occurred during hook creation'),
335 category='error')
330 if update:
331 h.flash(_('Updated hooks'), category='success')
332 Session().commit()
333 except Exception:
334 log.error(traceback.format_exc())
335 h.flash(_('Error occurred during hook creation'),
336 category='error')
336 337
337 338 return redirect(url('admin_edit_setting', setting_id='hooks'))
338 339
339 340 if setting_id == 'email':
340 341 test_email = request.POST.get('test_email')
341 342 test_email_subj = 'RhodeCode TestEmail'
342 343 test_email_body = 'RhodeCode Email test'
343 344
344 345 test_email_html_body = EmailNotificationModel()\
345 346 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
346 347 body=test_email_body)
347 348
348 349 recipients = [test_email] if test_email else None
349 350
350 351 run_task(tasks.send_email, recipients, test_email_subj,
351 352 test_email_body, test_email_html_body)
352 353
353 354 h.flash(_('Email task created'), category='success')
354 355 return redirect(url('admin_settings'))
355 356
356 357 @HasPermissionAllDecorator('hg.admin')
357 358 def delete(self, setting_id):
358 359 """DELETE /admin/settings/setting_id: Delete an existing item"""
359 360 # Forms posted to this method should contain a hidden field:
360 361 # <input type="hidden" name="_method" value="DELETE" />
361 362 # Or using helpers:
362 363 # h.form(url('admin_setting', setting_id=ID),
363 364 # method='delete')
364 365 # url('admin_setting', setting_id=ID)
365 366 if setting_id == 'hooks':
366 367 hook_id = request.POST.get('hook_id')
367 368 RhodeCodeUi.delete(hook_id)
368 369 Session().commit()
369 370
370 371 @HasPermissionAllDecorator('hg.admin')
371 372 def show(self, setting_id, format='html'):
372 373 """
373 374 GET /admin/settings/setting_id: Show a specific item"""
374 375 # url('admin_setting', setting_id=ID)
375 376
376 377 @HasPermissionAllDecorator('hg.admin')
377 378 def edit(self, setting_id, format='html'):
378 379 """
379 380 GET /admin/settings/setting_id/edit: Form to
380 381 edit an existing item"""
381 382 # url('admin_edit_setting', setting_id=ID)
382 383
383 384 c.hooks = RhodeCodeUi.get_builtin_hooks()
384 385 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
385 386
386 387 return htmlfill.render(
387 388 render('admin/settings/hooks.html'),
388 389 defaults={},
389 390 encoding="UTF-8",
390 391 force_defaults=False
391 392 )
392 393
393 394 def _load_my_repos_data(self):
394 395 repos_list = Session().query(Repository)\
395 396 .filter(Repository.user_id ==
396 397 self.rhodecode_user.user_id)\
397 398 .order_by(func.lower(Repository.repo_name)).all()
398 399
399 400 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
400 401 admin=True)
401 402 #json used to render the grid
402 403 return json.dumps(repos_data)
403 404
404 405 @NotAnonymous()
405 406 def my_account(self):
406 407 """
407 408 GET /_admin/my_account Displays info about my account
408 409 """
409 410 # url('admin_settings_my_account')
410 411
411 412 c.user = User.get(self.rhodecode_user.user_id)
412 413 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
413 414 ip_addr=self.ip_addr)
414 415 c.ldap_dn = c.user.ldap_dn
415 416
416 417 if c.user.username == 'default':
417 418 h.flash(_("You can't edit this user since it's"
418 419 " crucial for entire application"), category='warning')
419 420 return redirect(url('users'))
420 421
421 422 #json used to render the grid
422 423 c.data = self._load_my_repos_data()
423 424
424 425 defaults = c.user.get_dict()
425 426
426 427 c.form = htmlfill.render(
427 428 render('admin/users/user_edit_my_account_form.html'),
428 429 defaults=defaults,
429 430 encoding="UTF-8",
430 431 force_defaults=False
431 432 )
432 433 return render('admin/users/user_edit_my_account.html')
433 434
434 435 @NotAnonymous()
435 436 def my_account_update(self):
436 437 """PUT /_admin/my_account_update: Update an existing item"""
437 438 # Forms posted to this method should contain a hidden field:
438 439 # <input type="hidden" name="_method" value="PUT" />
439 440 # Or using helpers:
440 441 # h.form(url('admin_settings_my_account_update'),
441 442 # method='put')
442 443 # url('admin_settings_my_account_update', id=ID)
443 444 uid = self.rhodecode_user.user_id
444 445 c.user = User.get(self.rhodecode_user.user_id)
445 446 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
446 447 ip_addr=self.ip_addr)
447 448 c.ldap_dn = c.user.ldap_dn
448 449 email = self.rhodecode_user.email
449 450 _form = UserForm(edit=True,
450 451 old_data={'user_id': uid, 'email': email})()
451 452 form_result = {}
452 453 try:
453 454 form_result = _form.to_python(dict(request.POST))
454 455 skip_attrs = ['admin', 'active'] # skip attr for my account
455 456 if c.ldap_dn:
456 457 #forbid updating username for ldap accounts
457 458 skip_attrs.append('username')
458 459 UserModel().update(uid, form_result, skip_attrs=skip_attrs)
459 460 h.flash(_('Your account was updated successfully'),
460 461 category='success')
461 462 Session().commit()
462 463 except formencode.Invalid, errors:
463 464 #json used to render the grid
464 465 c.data = self._load_my_repos_data()
465 466 c.form = htmlfill.render(
466 467 render('admin/users/user_edit_my_account_form.html'),
467 468 defaults=errors.value,
468 469 errors=errors.error_dict or {},
469 470 prefix_error=False,
470 471 encoding="UTF-8")
471 472 return render('admin/users/user_edit_my_account.html')
472 473 except Exception:
473 474 log.error(traceback.format_exc())
474 475 h.flash(_('Error occurred during update of user %s') \
475 476 % form_result.get('username'), category='error')
476 477
477 478 return redirect(url('my_account'))
478 479
479 480 @NotAnonymous()
480 481 def my_account_my_pullrequests(self):
481 482 c.show_closed = request.GET.get('pr_show_closed')
482 483
483 484 def _filter(pr):
484 485 s = sorted(pr, key=lambda o: o.created_on, reverse=True)
485 486 if not c.show_closed:
486 487 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s)
487 488 return s
488 489
489 490 c.my_pull_requests = _filter(PullRequest.query()\
490 491 .filter(PullRequest.user_id ==
491 492 self.rhodecode_user.user_id)\
492 493 .all())
493 494
494 495 c.participate_in_pull_requests = _filter([
495 496 x.pull_request for x in PullRequestReviewers.query()\
496 497 .filter(PullRequestReviewers.user_id ==
497 498 self.rhodecode_user.user_id).all()])
498 499
499 500 return render('admin/users/user_edit_my_account_pullrequests.html')
500 501
501 502 def _get_hg_ui_settings(self):
502 503 ret = RhodeCodeUi.query().all()
503 504
504 505 if not ret:
505 506 raise Exception('Could not get application ui settings !')
506 507 settings = {}
507 508 for each in ret:
508 509 k = each.ui_key
509 510 v = each.ui_value
510 511 if k == '/':
511 512 k = 'root_path'
512 513
513 514 if k == 'push_ssl':
514 515 v = str2bool(v)
515 516
516 517 if k.find('.') != -1:
517 518 k = k.replace('.', '_')
518 519
519 520 if each.ui_section in ['hooks', 'extensions']:
520 521 v = each.ui_active
521 522
522 523 settings[each.ui_section + '_' + k] = v
523 524 return settings
@@ -1,349 +1,350 b''
1 1 """The base Controller API
2 2
3 3 Provides the BaseController class for subclassing.
4 4 """
5 5 import logging
6 6 import time
7 7 import traceback
8 8
9 9 from paste.auth.basic import AuthBasicAuthenticator
10 10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
11 11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
12 12
13 13 from pylons import config, tmpl_context as c, request, session, url
14 14 from pylons.controllers import WSGIController
15 15 from pylons.controllers.util import redirect
16 16 from pylons.templating import render_mako as render
17 17
18 18 from rhodecode import __version__, BACKENDS
19 19
20 20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
21 21 safe_str, safe_int
22 22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
23 23 HasPermissionAnyMiddleware, CookieStoreWrapper
24 24 from rhodecode.lib.utils import get_repo_slug
25 25 from rhodecode.model import meta
26 26
27 27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
28 28 from rhodecode.model.notification import NotificationModel
29 29 from rhodecode.model.scm import ScmModel
30 30 from rhodecode.model.meta import Session
31 31
32 32 log = logging.getLogger(__name__)
33 33
34 34
35 35 def _filter_proxy(ip):
36 36 """
37 37 HEADERS can have multiple ips inside the left-most being the original
38 38 client, and each successive proxy that passed the request adding the IP
39 39 address where it received the request from.
40 40
41 41 :param ip:
42 42 """
43 43 if ',' in ip:
44 44 _ips = ip.split(',')
45 45 _first_ip = _ips[0].strip()
46 46 log.debug('Got multiple IPs %s, using %s' % (','.join(_ips), _first_ip))
47 47 return _first_ip
48 48 return ip
49 49
50 50
51 51 def _get_ip_addr(environ):
52 52 proxy_key = 'HTTP_X_REAL_IP'
53 53 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
54 54 def_key = 'REMOTE_ADDR'
55 55
56 56 ip = environ.get(proxy_key)
57 57 if ip:
58 58 return _filter_proxy(ip)
59 59
60 60 ip = environ.get(proxy_key2)
61 61 if ip:
62 62 return _filter_proxy(ip)
63 63
64 64 ip = environ.get(def_key, '0.0.0.0')
65 65 return _filter_proxy(ip)
66 66
67 67
68 68 def _get_access_path(environ):
69 69 path = environ.get('PATH_INFO')
70 70 org_req = environ.get('pylons.original_request')
71 71 if org_req:
72 72 path = org_req.environ.get('PATH_INFO')
73 73 return path
74 74
75 75
76 76 class BasicAuth(AuthBasicAuthenticator):
77 77
78 78 def __init__(self, realm, authfunc, auth_http_code=None):
79 79 self.realm = realm
80 80 self.authfunc = authfunc
81 81 self._rc_auth_http_code = auth_http_code
82 82
83 83 def build_authentication(self):
84 84 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
85 85 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
86 86 # return 403 if alternative http return code is specified in
87 87 # RhodeCode config
88 88 return HTTPForbidden(headers=head)
89 89 return HTTPUnauthorized(headers=head)
90 90
91 91 def authenticate(self, environ):
92 92 authorization = AUTHORIZATION(environ)
93 93 if not authorization:
94 94 return self.build_authentication()
95 95 (authmeth, auth) = authorization.split(' ', 1)
96 96 if 'basic' != authmeth.lower():
97 97 return self.build_authentication()
98 98 auth = auth.strip().decode('base64')
99 99 _parts = auth.split(':', 1)
100 100 if len(_parts) == 2:
101 101 username, password = _parts
102 102 if self.authfunc(environ, username, password):
103 103 return username
104 104 return self.build_authentication()
105 105
106 106 __call__ = authenticate
107 107
108 108
109 109 class BaseVCSController(object):
110 110
111 111 def __init__(self, application, config):
112 112 self.application = application
113 113 self.config = config
114 114 # base path of repo locations
115 115 self.basepath = self.config['base_path']
116 116 #authenticate this mercurial request using authfunc
117 117 self.authenticate = BasicAuth('', authfunc,
118 118 config.get('auth_ret_code'))
119 119 self.ip_addr = '0.0.0.0'
120 120
121 121 def _handle_request(self, environ, start_response):
122 122 raise NotImplementedError()
123 123
124 124 def _get_by_id(self, repo_name):
125 125 """
126 126 Get's a special pattern _<ID> from clone url and tries to replace it
127 127 with a repository_name for support of _<ID> non changable urls
128 128
129 129 :param repo_name:
130 130 """
131 131 try:
132 132 data = repo_name.split('/')
133 133 if len(data) >= 2:
134 134 by_id = data[1].split('_')
135 135 if len(by_id) == 2 and by_id[1].isdigit():
136 136 _repo_name = Repository.get(by_id[1]).repo_name
137 137 data[1] = _repo_name
138 138 except Exception:
139 139 log.debug('Failed to extract repo_name from id %s' % (
140 140 traceback.format_exc()
141 141 )
142 142 )
143 143
144 144 return '/'.join(data)
145 145
146 146 def _invalidate_cache(self, repo_name):
147 147 """
148 148 Set's cache for this repository for invalidation on next access
149 149
150 150 :param repo_name: full repo name, also a cache key
151 151 """
152 152 ScmModel().mark_for_invalidation(repo_name)
153 153
154 154 def _check_permission(self, action, user, repo_name, ip_addr=None):
155 155 """
156 156 Checks permissions using action (push/pull) user and repository
157 157 name
158 158
159 159 :param action: push or pull action
160 160 :param user: user instance
161 161 :param repo_name: repository name
162 162 """
163 163 #check IP
164 164 authuser = AuthUser(user_id=user.user_id, ip_addr=ip_addr)
165 165 if not authuser.ip_allowed:
166 166 return False
167 167 else:
168 168 log.info('Access for IP:%s allowed' % (ip_addr))
169 169 if action == 'push':
170 170 if not HasPermissionAnyMiddleware('repository.write',
171 171 'repository.admin')(user,
172 172 repo_name):
173 173 return False
174 174
175 175 else:
176 176 #any other action need at least read permission
177 177 if not HasPermissionAnyMiddleware('repository.read',
178 178 'repository.write',
179 179 'repository.admin')(user,
180 180 repo_name):
181 181 return False
182 182
183 183 return True
184 184
185 185 def _get_ip_addr(self, environ):
186 186 return _get_ip_addr(environ)
187 187
188 188 def _check_ssl(self, environ, start_response):
189 189 """
190 190 Checks the SSL check flag and returns False if SSL is not present
191 191 and required True otherwise
192 192 """
193 193 org_proto = environ['wsgi._org_proto']
194 194 #check if we have SSL required ! if not it's a bad request !
195 195 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
196 196 if require_ssl and org_proto == 'http':
197 197 log.debug('proto is %s and SSL is required BAD REQUEST !'
198 198 % org_proto)
199 199 return False
200 200 return True
201 201
202 202 def _check_locking_state(self, environ, action, repo, user_id):
203 203 """
204 204 Checks locking on this repository, if locking is enabled and lock is
205 205 present returns a tuple of make_lock, locked, locked_by.
206 206 make_lock can have 3 states None (do nothing) True, make lock
207 207 False release lock, This value is later propagated to hooks, which
208 208 do the locking. Think about this as signals passed to hooks what to do.
209 209
210 210 """
211 211 locked = False # defines that locked error should be thrown to user
212 212 make_lock = None
213 213 repo = Repository.get_by_repo_name(repo)
214 214 user = User.get(user_id)
215 215
216 216 # this is kind of hacky, but due to how mercurial handles client-server
217 217 # server see all operation on changeset; bookmarks, phases and
218 218 # obsolescence marker in different transaction, we don't want to check
219 219 # locking on those
220 220 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
221 221 locked_by = repo.locked
222 222 if repo and repo.enable_locking and not obsolete_call:
223 223 if action == 'push':
224 224 #check if it's already locked !, if it is compare users
225 225 user_id, _date = repo.locked
226 226 if user.user_id == user_id:
227 227 log.debug('Got push from user %s, now unlocking' % (user))
228 228 # unlock if we have push from user who locked
229 229 make_lock = False
230 230 else:
231 231 # we're not the same user who locked, ban with 423 !
232 232 locked = True
233 233 if action == 'pull':
234 234 if repo.locked[0] and repo.locked[1]:
235 235 locked = True
236 236 else:
237 237 log.debug('Setting lock on repo %s by %s' % (repo, user))
238 238 make_lock = True
239 239
240 240 else:
241 241 log.debug('Repository %s do not have locking enabled' % (repo))
242 242 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
243 243 % (make_lock, locked, locked_by))
244 244 return make_lock, locked, locked_by
245 245
246 246 def __call__(self, environ, start_response):
247 247 start = time.time()
248 248 try:
249 249 return self._handle_request(environ, start_response)
250 250 finally:
251 251 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
252 252 log.debug('Request time: %.3fs' % (time.time() - start))
253 253 meta.Session.remove()
254 254
255 255
256 256 class BaseController(WSGIController):
257 257
258 258 def __before__(self):
259 259 """
260 260 __before__ is called before controller methods and after __call__
261 261 """
262 262 c.rhodecode_version = __version__
263 263 c.rhodecode_instanceid = config.get('instance_id')
264 264 c.rhodecode_name = config.get('rhodecode_title')
265 265 c.rhodecode_bugtracker = config.get('bugtracker', 'http://bitbucket.org/marcinkuzminski/rhodecode/issues')
266 266 c.use_gravatar = str2bool(config.get('use_gravatar'))
267 267 c.ga_code = config.get('rhodecode_ga_code')
268 268 # Visual options
269 269 c.visual = AttributeDict({})
270 270 rc_config = RhodeCodeSetting.get_app_settings()
271 271 ## DB stored
272 272 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
273 273 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
274 274 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
275 275 c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
276 276 c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
277 277 c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))
278 278
279 279 ## INI stored
280 280 self.cut_off_limit = int(config.get('cut_off_limit'))
281 281 c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
282 c.visual.allow_custom_hooks_settings = str2bool(config.get('allow_custom_hooks_settings', True))
282 283
283 284 c.repo_name = get_repo_slug(request) # can be empty
284 285 c.backends = BACKENDS.keys()
285 286 c.unread_notifications = NotificationModel()\
286 287 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
287 288 self.sa = meta.Session
288 289 self.scm_model = ScmModel(self.sa)
289 290
290 291 def __call__(self, environ, start_response):
291 292 """Invoke the Controller"""
292 293 # WSGIController.__call__ dispatches to the Controller method
293 294 # the request is routed to. This routing information is
294 295 # available in environ['pylons.routes_dict']
295 296 try:
296 297 self.ip_addr = _get_ip_addr(environ)
297 298 # make sure that we update permissions each time we call controller
298 299 api_key = request.GET.get('api_key')
299 300 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
300 301 user_id = cookie_store.get('user_id', None)
301 302 username = get_container_username(environ, config)
302 303 auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
303 304 request.user = auth_user
304 305 self.rhodecode_user = c.rhodecode_user = auth_user
305 306 if not self.rhodecode_user.is_authenticated and \
306 307 self.rhodecode_user.user_id is not None:
307 308 self.rhodecode_user.set_authenticated(
308 309 cookie_store.get('is_authenticated')
309 310 )
310 311 log.info('IP: %s User: %s accessed %s' % (
311 312 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
312 313 )
313 314 return WSGIController.__call__(self, environ, start_response)
314 315 finally:
315 316 meta.Session.remove()
316 317
317 318
318 319 class BaseRepoController(BaseController):
319 320 """
320 321 Base class for controllers responsible for loading all needed data for
321 322 repository loaded items are
322 323
323 324 c.rhodecode_repo: instance of scm repository
324 325 c.rhodecode_db_repo: instance of db
325 326 c.repository_followers: number of followers
326 327 c.repository_forks: number of forks
327 328 c.repository_following: weather the current user is following the current repo
328 329 """
329 330
330 331 def __before__(self):
331 332 super(BaseRepoController, self).__before__()
332 333 if c.repo_name:
333 334
334 335 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
335 336 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
336 337 # update last change according to VCS data
337 338 dbr.update_changeset_cache(dbr.get_changeset())
338 339 if c.rhodecode_repo is None:
339 340 log.error('%s this repository is present in database but it '
340 341 'cannot be created as an scm instance', c.repo_name)
341 342
342 343 redirect(url('home'))
343 344
344 345 # some globals counter for menu
345 346 c.repository_followers = self.scm_model.get_followers(dbr)
346 347 c.repository_forks = self.scm_model.get_forks(dbr)
347 348 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
348 349 c.repository_following = self.scm_model.is_following_repo(c.repo_name,
349 350 self.rhodecode_user.user_id)
@@ -1,96 +1,97 b''
1 1 ## -*- coding: utf-8 -*-
2 2 <%inherit file="/base/base.html"/>
3 3
4 4 <%def name="title()">
5 5 ${_('Settings administration')} &middot; ${c.rhodecode_name}
6 6 </%def>
7 7
8 8 <%def name="breadcrumbs_links()">
9 9 ${h.link_to(_('Admin'),h.url('admin_home'))} &raquo; ${_('Settings')}
10 10 </%def>
11 11
12 12 <%def name="page_nav()">
13 13 ${self.menu('admin')}
14 14 </%def>
15 15
16 16 <%def name="main()">
17 17 <div class="box">
18 18 <!-- box / title -->
19 19 <div class="title">
20 20 ${self.breadcrumbs()}
21 21 </div>
22 22 <!-- end box / title -->
23 23
24 24 <h3>${_('Built in hooks - read only')}</h3>
25 25 <div class="form">
26 26 <div class="fields">
27 27 % for hook in c.hooks:
28 28 <div class="field">
29 29 <div class="label label">
30 30 <label for="${hook.ui_key}">${hook.ui_key}</label>
31 31 </div>
32 32 <div class="input" style="margin-left:280px">
33 33 ${h.text(hook.ui_key,hook.ui_value,size=60,readonly="readonly")}
34 34 </div>
35 35 </div>
36 36 % endfor
37 37 </div>
38 38 </div>
39
39 % if c.visual.allow_custom_hooks_settings:
40 40 <h3>${_('Custom hooks')}</h3>
41 41 ${h.form(url('admin_setting', setting_id='hooks'),method='put')}
42 42 <div class="form">
43 43 <div class="fields">
44 44
45 45 % for hook in c.custom_hooks:
46 46 <div class="field" id="${'id%s' % hook.ui_id }">
47 47 <div class="label label">
48 48 <label for="${hook.ui_key}">${hook.ui_key}</label>
49 49 </div>
50 50 <div class="input" style="margin-left:280px">
51 51 ${h.hidden('hook_ui_key',hook.ui_key)}
52 52 ${h.hidden('hook_ui_value',hook.ui_value)}
53 53 ${h.text('hook_ui_value_new',hook.ui_value,size=60)}
54 54 <span class="delete_icon action_button"
55 55 onclick="ajaxActionHook(${hook.ui_id},'${'id%s' % hook.ui_id }')">
56 56 ${_('remove')}
57 57 </span>
58 58 </div>
59 59 </div>
60 60 % endfor
61 61
62 62 <div class="field">
63 63 <div class="input" style="margin-left:-180px;position: absolute;">
64 64 <div class="input">
65 65 ${h.text('new_hook_ui_key',size=30)}
66 66 </div>
67 67 </div>
68 68 <div class="input" style="margin-left:280px">
69 69 ${h.text('new_hook_ui_value',size=60)}
70 70 </div>
71 71 </div>
72 72 <div class="buttons" style="margin-left:280px">
73 73 ${h.submit('save',_('Save'),class_="ui-btn large")}
74 74 </div>
75 75 </div>
76 76 </div>
77 77 ${h.end_form()}
78 % endif
78 79 </div>
79 80 <script type="text/javascript">
80 81 function ajaxActionHook(hook_id,field_id) {
81 82 var sUrl = "${h.url('admin_setting', setting_id='hooks')}";
82 83 var callback = {
83 84 success: function (o) {
84 85 var elem = YUD.get(""+field_id);
85 86 elem.parentNode.removeChild(elem);
86 87 },
87 88 failure: function (o) {
88 89 alert("${_('Failed to remove hook')}");
89 90 },
90 91 };
91 92 var postData = '_method=delete&hook_id=' + hook_id;
92 93 var request = YAHOO.util.Connect.asyncRequest('POST', sUrl, callback, postData);
93 94 };
94 95 </script>
95 96
96 97 </%def>
General Comments 0
You need to be logged in to leave comments. Login now