##// END OF EJS Templates
Added flag to controll option for changing the repos path location...
marcink -
r3920:985db7f7 beta
parent child Browse files
Show More
@@ -1,507 +1,508 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. Don't change that to more than 1
54 54 #workers = 1
55 55 ## process name
56 56 #proc_name = rhodecode
57 57 ## type of worker class, one of sync, eventlet, gevent, tornado
58 58 ## recommended for bigger setup is using of of other than sync one
59 59 #worker-class = sync
60 60 #max-requests = 5
61 61
62 62 ## COMMON ##
63 63 host = 0.0.0.0
64 64 port = 5000
65 65
66 66 ## prefix middleware for rc
67 67 #[filter:proxy-prefix]
68 68 #use = egg:PasteDeploy#prefix
69 69 #prefix = /<your-prefix>
70 70
71 71 [app:main]
72 72 use = egg:rhodecode
73 73 ## enable proxy prefix middleware
74 74 #filter-with = proxy-prefix
75 75
76 76 full_stack = true
77 77 static_files = true
78 78 ## Optional Languages
79 79 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
80 80 lang = en
81 81 cache_dir = %(here)s/data
82 82 index_dir = %(here)s/data/index
83 83
84 84 ## perform a full repository scan on each server start, this should be
85 85 ## set to false after first startup, to allow faster server restarts.
86 86 initial_repo_scan = true
87 87
88 88 ## uncomment and set this path to use archive download cache
89 89 #archive_cache_dir = /tmp/tarballcache
90 90
91 91 ## change this to unique ID for security
92 92 app_instance_uuid = rc-production
93 93
94 94 ## cut off limit for large diffs (size in bytes)
95 95 cut_off_limit = 256000
96 96
97 97 ## use cache version of scm repo everywhere
98 98 vcs_full_cache = true
99 99
100 100 ## force https in RhodeCode, fixes https redirects, assumes it's always https
101 101 force_https = false
102 102
103 103 ## use Strict-Transport-Security headers
104 104 use_htsts = false
105 105
106 106 ## number of commits stats will parse on each iteration
107 107 commit_parse_limit = 25
108 108
109 109 ## use gravatar service to display avatars
110 110 use_gravatar = true
111 111
112 112 ## path to git executable
113 113 git_path = git
114 114
115 115 ## git rev filter option, --all is the default filter, if you need to
116 116 ## hide all refs in changelog switch this to --branches --tags
117 117 git_rev_filter=--all
118 118
119 119 ## RSS feed options
120 120 rss_cut_off_limit = 256000
121 121 rss_items_per_page = 10
122 122 rss_include_diff = false
123 123
124 124 ## options for showing and identifying changesets
125 125 show_sha_length = 12
126 126 show_revision_number = true
127 127
128 128 ## gist URL alias, used to create nicer urls for gist. This should be an
129 129 ## url that does rewrites to _admin/gists/<gistid>.
130 130 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
131 131 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
132 132 gist_alias_url =
133 133
134 134 ## white list of API enabled controllers. This allows to add list of
135 135 ## controllers to which access will be enabled by api_key. eg: to enable
136 136 ## api access to raw_files put `FilesController:raw`, to enable access to patches
137 137 ## add `ChangesetController:changeset_patch`. This list should be "," separated
138 138 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
139 139 api_access_controllers_whitelist =
140 140
141 141 ## alternative_gravatar_url allows you to use your own avatar server application
142 142 ## the following parts of the URL will be replaced
143 143 ## {email} user email
144 144 ## {md5email} md5 hash of the user email (like at gravatar.com)
145 145 ## {size} size of the image that is expected from the server application
146 146 ## {scheme} http/https from RhodeCode server
147 147 ## {netloc} network location from RhodeCode server
148 148 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
149 149 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
150 150
151 151
152 152 ## container auth options
153 153 container_auth_enabled = false
154 154 proxypass_auth_enabled = false
155 155
156 156 ## default encoding used to convert from and to unicode
157 157 ## can be also a comma seperated list of encoding in case of mixed encodings
158 158 default_encoding = utf8
159 159
160 160 ## overwrite schema of clone url
161 161 ## available vars:
162 162 ## scheme - http/https
163 163 ## user - current user
164 164 ## pass - password
165 165 ## netloc - network location
166 166 ## path - usually repo_name
167 167
168 168 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
169 169
170 170 ## issue tracking mapping for commits messages
171 171 ## comment out issue_pat, issue_server, issue_prefix to enable
172 172
173 173 ## pattern to get the issues from commit messages
174 174 ## default one used here is #<numbers> with a regex passive group for `#`
175 175 ## {id} will be all groups matched from this pattern
176 176
177 177 issue_pat = (?:\s*#)(\d+)
178 178
179 179 ## server url to the issue, each {id} will be replaced with match
180 180 ## fetched from the regex and {repo} is replaced with full repository name
181 181 ## including groups {repo_name} is replaced with just name of repo
182 182
183 183 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
184 184
185 185 ## prefix to add to link to indicate it's an url
186 186 ## #314 will be replaced by <issue_prefix><id>
187 187
188 188 issue_prefix = #
189 189
190 190 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
191 191 ## multiple patterns, to other issues server, wiki or others
192 192 ## below an example how to create a wiki pattern
193 193 # #wiki-some-id -> https://mywiki.com/some-id
194 194
195 195 #issue_pat_wiki = (?:wiki-)(.+)
196 196 #issue_server_link_wiki = https://mywiki.com/{id}
197 197 #issue_prefix_wiki = WIKI-
198 198
199 199
200 200 ## instance-id prefix
201 201 ## a prefix key for this instance used for cache invalidation when running
202 202 ## multiple instances of rhodecode, make sure it's globally unique for
203 203 ## all running rhodecode instances. Leave empty if you don't use it
204 204 instance_id =
205 205
206 206 ## alternative return HTTP header for failed authentication. Default HTTP
207 207 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
208 208 ## handling that. Set this variable to 403 to return HTTPForbidden
209 209 auth_ret_code =
210 210
211 211 ## locking return code. When repository is locked return this HTTP code. 2XX
212 212 ## codes don't break the transactions while 4XX codes do
213 213 lock_ret_code = 423
214 214
215 allow_repo_location_change = True
215 216
216 217 ####################################
217 218 ### CELERY CONFIG ####
218 219 ####################################
219 220 use_celery = false
220 221 broker.host = localhost
221 222 broker.vhost = rabbitmqhost
222 223 broker.port = 5672
223 224 broker.user = rabbitmq
224 225 broker.password = qweqwe
225 226
226 227 celery.imports = rhodecode.lib.celerylib.tasks
227 228
228 229 celery.result.backend = amqp
229 230 celery.result.dburi = amqp://
230 231 celery.result.serialier = json
231 232
232 233 #celery.send.task.error.emails = true
233 234 #celery.amqp.task.result.expires = 18000
234 235
235 236 celeryd.concurrency = 2
236 237 #celeryd.log.file = celeryd.log
237 238 celeryd.log.level = debug
238 239 celeryd.max.tasks.per.child = 1
239 240
240 241 ## tasks will never be sent to the queue, but executed locally instead.
241 242 celery.always.eager = false
242 243
243 244 ####################################
244 245 ### BEAKER CACHE ####
245 246 ####################################
246 247 beaker.cache.data_dir=%(here)s/data/cache/data
247 248 beaker.cache.lock_dir=%(here)s/data/cache/lock
248 249
249 250 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
250 251
251 252 beaker.cache.super_short_term.type=memory
252 253 beaker.cache.super_short_term.expire=10
253 254 beaker.cache.super_short_term.key_length = 256
254 255
255 256 beaker.cache.short_term.type=memory
256 257 beaker.cache.short_term.expire=60
257 258 beaker.cache.short_term.key_length = 256
258 259
259 260 beaker.cache.long_term.type=memory
260 261 beaker.cache.long_term.expire=36000
261 262 beaker.cache.long_term.key_length = 256
262 263
263 264 beaker.cache.sql_cache_short.type=memory
264 265 beaker.cache.sql_cache_short.expire=10
265 266 beaker.cache.sql_cache_short.key_length = 256
266 267
267 268 beaker.cache.sql_cache_med.type=memory
268 269 beaker.cache.sql_cache_med.expire=360
269 270 beaker.cache.sql_cache_med.key_length = 256
270 271
271 272 beaker.cache.sql_cache_long.type=file
272 273 beaker.cache.sql_cache_long.expire=3600
273 274 beaker.cache.sql_cache_long.key_length = 256
274 275
275 276 ####################################
276 277 ### BEAKER SESSION ####
277 278 ####################################
278 279 ## Type of storage used for the session, current types are
279 280 ## dbm, file, memcached, database, and memory.
280 281 ## The storage uses the Container API
281 282 ## that is also used by the cache system.
282 283
283 284 ## db session ##
284 285 #beaker.session.type = ext:database
285 286 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
286 287 #beaker.session.table_name = db_session
287 288
288 289 ## encrypted cookie client side session, good for many instances ##
289 290 #beaker.session.type = cookie
290 291
291 292 ## file based cookies (default) ##
292 293 #beaker.session.type = file
293 294
294 295
295 296 beaker.session.key = rhodecode
296 297 ## secure cookie requires AES python libraries
297 298 #beaker.session.encrypt_key = <key_for_encryption>
298 299 #beaker.session.validate_key = <validation_key>
299 300
300 301 ## sets session as invalid if it haven't been accessed for given amount of time
301 302 beaker.session.timeout = 2592000
302 303 beaker.session.httponly = true
303 304 #beaker.session.cookie_path = /<your-prefix>
304 305
305 306 ## uncomment for https secure cookie
306 307 beaker.session.secure = false
307 308
308 309 ## auto save the session to not to use .save()
309 310 beaker.session.auto = False
310 311
311 312 ## default cookie expiration time in seconds `true` expire at browser close ##
312 313 #beaker.session.cookie_expires = 3600
313 314
314 315
315 316 ############################
316 317 ## ERROR HANDLING SYSTEMS ##
317 318 ############################
318 319
319 320 ####################
320 321 ### [errormator] ###
321 322 ####################
322 323
323 324 ## Errormator is tailored to work with RhodeCode, see
324 325 ## http://errormator.com for details how to obtain an account
325 326 ## you must install python package `errormator_client` to make it work
326 327
327 328 ## errormator enabled
328 329 errormator = false
329 330
330 331 errormator.server_url = https://api.errormator.com
331 332 errormator.api_key = YOUR_API_KEY
332 333
333 334 ## TWEAK AMOUNT OF INFO SENT HERE
334 335
335 336 ## enables 404 error logging (default False)
336 337 errormator.report_404 = false
337 338
338 339 ## time in seconds after request is considered being slow (default 1)
339 340 errormator.slow_request_time = 1
340 341
341 342 ## record slow requests in application
342 343 ## (needs to be enabled for slow datastore recording and time tracking)
343 344 errormator.slow_requests = true
344 345
345 346 ## enable hooking to application loggers
346 347 # errormator.logging = true
347 348
348 349 ## minimum log level for log capture
349 350 # errormator.logging.level = WARNING
350 351
351 352 ## send logs only from erroneous/slow requests
352 353 ## (saves API quota for intensive logging)
353 354 errormator.logging_on_error = false
354 355
355 356 ## list of additonal keywords that should be grabbed from environ object
356 357 ## can be string with comma separated list of words in lowercase
357 358 ## (by default client will always send following info:
358 359 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
359 360 ## start with HTTP* this list be extended with additional keywords here
360 361 errormator.environ_keys_whitelist =
361 362
362 363
363 364 ## list of keywords that should be blanked from request object
364 365 ## can be string with comma separated list of words in lowercase
365 366 ## (by default client will always blank keys that contain following words
366 367 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
367 368 ## this list be extended with additional keywords set here
368 369 errormator.request_keys_blacklist =
369 370
370 371
371 372 ## list of namespaces that should be ignores when gathering log entries
372 373 ## can be string with comma separated list of namespaces
373 374 ## (by default the client ignores own entries: errormator_client.client)
374 375 errormator.log_namespace_blacklist =
375 376
376 377
377 378 ################
378 379 ### [sentry] ###
379 380 ################
380 381
381 382 ## sentry is a alternative open source error aggregator
382 383 ## you must install python packages `sentry` and `raven` to enable
383 384
384 385 sentry.dsn = YOUR_DNS
385 386 sentry.servers =
386 387 sentry.name =
387 388 sentry.key =
388 389 sentry.public_key =
389 390 sentry.secret_key =
390 391 sentry.project =
391 392 sentry.site =
392 393 sentry.include_paths =
393 394 sentry.exclude_paths =
394 395
395 396
396 397 ################################################################################
397 398 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
398 399 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
399 400 ## execute malicious code after an exception is raised. ##
400 401 ################################################################################
401 402 #set debug = false
402 403
403 404 ##################################
404 405 ### LOGVIEW CONFIG ###
405 406 ##################################
406 407 logview.sqlalchemy = #faa
407 408 logview.pylons.templating = #bfb
408 409 logview.pylons.util = #eee
409 410
410 411 #########################################################
411 412 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
412 413 #########################################################
413 414 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
414 415 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
415 416 sqlalchemy.db1.echo = false
416 417 sqlalchemy.db1.pool_recycle = 3600
417 418 sqlalchemy.db1.convert_unicode = true
418 419
419 420 ################################
420 421 ### LOGGING CONFIGURATION ####
421 422 ################################
422 423 [loggers]
423 424 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
424 425
425 426 [handlers]
426 427 keys = console, console_sql
427 428
428 429 [formatters]
429 430 keys = generic, color_formatter, color_formatter_sql
430 431
431 432 #############
432 433 ## LOGGERS ##
433 434 #############
434 435 [logger_root]
435 436 level = NOTSET
436 437 handlers = console
437 438
438 439 [logger_routes]
439 440 level = DEBUG
440 441 handlers =
441 442 qualname = routes.middleware
442 443 ## "level = DEBUG" logs the route matched and routing variables.
443 444 propagate = 1
444 445
445 446 [logger_beaker]
446 447 level = DEBUG
447 448 handlers =
448 449 qualname = beaker.container
449 450 propagate = 1
450 451
451 452 [logger_templates]
452 453 level = INFO
453 454 handlers =
454 455 qualname = pylons.templating
455 456 propagate = 1
456 457
457 458 [logger_rhodecode]
458 459 level = DEBUG
459 460 handlers =
460 461 qualname = rhodecode
461 462 propagate = 1
462 463
463 464 [logger_sqlalchemy]
464 465 level = INFO
465 466 handlers = console_sql
466 467 qualname = sqlalchemy.engine
467 468 propagate = 0
468 469
469 470 [logger_whoosh_indexer]
470 471 level = DEBUG
471 472 handlers =
472 473 qualname = whoosh_indexer
473 474 propagate = 1
474 475
475 476 ##############
476 477 ## HANDLERS ##
477 478 ##############
478 479
479 480 [handler_console]
480 481 class = StreamHandler
481 482 args = (sys.stderr,)
482 483 level = DEBUG
483 484 formatter = color_formatter
484 485
485 486 [handler_console_sql]
486 487 class = StreamHandler
487 488 args = (sys.stderr,)
488 489 level = DEBUG
489 490 formatter = color_formatter_sql
490 491
491 492 ################
492 493 ## FORMATTERS ##
493 494 ################
494 495
495 496 [formatter_generic]
496 497 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
497 498 datefmt = %Y-%m-%d %H:%M:%S
498 499
499 500 [formatter_color_formatter]
500 501 class=rhodecode.lib.colored_formatter.ColorFormatter
501 502 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
502 503 datefmt = %Y-%m-%d %H:%M:%S
503 504
504 505 [formatter_color_formatter_sql]
505 506 class=rhodecode.lib.colored_formatter.ColorFormatterSql
506 507 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 508 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,507 +1,508 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. Don't change that to more than 1
54 54 #workers = 1
55 55 ## process name
56 56 #proc_name = rhodecode
57 57 ## type of worker class, one of sync, eventlet, gevent, tornado
58 58 ## recommended for bigger setup is using of of other than sync one
59 59 #worker-class = sync
60 60 #max-requests = 5
61 61
62 62 ## COMMON ##
63 63 host = 127.0.0.1
64 64 port = 5000
65 65
66 66 ## prefix middleware for rc
67 67 #[filter:proxy-prefix]
68 68 #use = egg:PasteDeploy#prefix
69 69 #prefix = /<your-prefix>
70 70
71 71 [app:main]
72 72 use = egg:rhodecode
73 73 ## enable proxy prefix middleware
74 74 #filter-with = proxy-prefix
75 75
76 76 full_stack = true
77 77 static_files = true
78 78 ## Optional Languages
79 79 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
80 80 lang = en
81 81 cache_dir = %(here)s/data
82 82 index_dir = %(here)s/data/index
83 83
84 84 ## perform a full repository scan on each server start, this should be
85 85 ## set to false after first startup, to allow faster server restarts.
86 86 initial_repo_scan = true
87 87
88 88 ## uncomment and set this path to use archive download cache
89 89 #archive_cache_dir = /tmp/tarballcache
90 90
91 91 ## change this to unique ID for security
92 92 app_instance_uuid = rc-production
93 93
94 94 ## cut off limit for large diffs (size in bytes)
95 95 cut_off_limit = 256000
96 96
97 97 ## use cache version of scm repo everywhere
98 98 vcs_full_cache = true
99 99
100 100 ## force https in RhodeCode, fixes https redirects, assumes it's always https
101 101 force_https = false
102 102
103 103 ## use Strict-Transport-Security headers
104 104 use_htsts = false
105 105
106 106 ## number of commits stats will parse on each iteration
107 107 commit_parse_limit = 25
108 108
109 109 ## use gravatar service to display avatars
110 110 use_gravatar = true
111 111
112 112 ## path to git executable
113 113 git_path = git
114 114
115 115 ## git rev filter option, --all is the default filter, if you need to
116 116 ## hide all refs in changelog switch this to --branches --tags
117 117 git_rev_filter=--all
118 118
119 119 ## RSS feed options
120 120 rss_cut_off_limit = 256000
121 121 rss_items_per_page = 10
122 122 rss_include_diff = false
123 123
124 124 ## options for showing and identifying changesets
125 125 show_sha_length = 12
126 126 show_revision_number = true
127 127
128 128 ## gist URL alias, used to create nicer urls for gist. This should be an
129 129 ## url that does rewrites to _admin/gists/<gistid>.
130 130 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
131 131 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
132 132 gist_alias_url =
133 133
134 134 ## white list of API enabled controllers. This allows to add list of
135 135 ## controllers to which access will be enabled by api_key. eg: to enable
136 136 ## api access to raw_files put `FilesController:raw`, to enable access to patches
137 137 ## add `ChangesetController:changeset_patch`. This list should be "," separated
138 138 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
139 139 api_access_controllers_whitelist =
140 140
141 141 ## alternative_gravatar_url allows you to use your own avatar server application
142 142 ## the following parts of the URL will be replaced
143 143 ## {email} user email
144 144 ## {md5email} md5 hash of the user email (like at gravatar.com)
145 145 ## {size} size of the image that is expected from the server application
146 146 ## {scheme} http/https from RhodeCode server
147 147 ## {netloc} network location from RhodeCode server
148 148 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
149 149 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
150 150
151 151
152 152 ## container auth options
153 153 container_auth_enabled = false
154 154 proxypass_auth_enabled = false
155 155
156 156 ## default encoding used to convert from and to unicode
157 157 ## can be also a comma seperated list of encoding in case of mixed encodings
158 158 default_encoding = utf8
159 159
160 160 ## overwrite schema of clone url
161 161 ## available vars:
162 162 ## scheme - http/https
163 163 ## user - current user
164 164 ## pass - password
165 165 ## netloc - network location
166 166 ## path - usually repo_name
167 167
168 168 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
169 169
170 170 ## issue tracking mapping for commits messages
171 171 ## comment out issue_pat, issue_server, issue_prefix to enable
172 172
173 173 ## pattern to get the issues from commit messages
174 174 ## default one used here is #<numbers> with a regex passive group for `#`
175 175 ## {id} will be all groups matched from this pattern
176 176
177 177 issue_pat = (?:\s*#)(\d+)
178 178
179 179 ## server url to the issue, each {id} will be replaced with match
180 180 ## fetched from the regex and {repo} is replaced with full repository name
181 181 ## including groups {repo_name} is replaced with just name of repo
182 182
183 183 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
184 184
185 185 ## prefix to add to link to indicate it's an url
186 186 ## #314 will be replaced by <issue_prefix><id>
187 187
188 188 issue_prefix = #
189 189
190 190 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
191 191 ## multiple patterns, to other issues server, wiki or others
192 192 ## below an example how to create a wiki pattern
193 193 # #wiki-some-id -> https://mywiki.com/some-id
194 194
195 195 #issue_pat_wiki = (?:wiki-)(.+)
196 196 #issue_server_link_wiki = https://mywiki.com/{id}
197 197 #issue_prefix_wiki = WIKI-
198 198
199 199
200 200 ## instance-id prefix
201 201 ## a prefix key for this instance used for cache invalidation when running
202 202 ## multiple instances of rhodecode, make sure it's globally unique for
203 203 ## all running rhodecode instances. Leave empty if you don't use it
204 204 instance_id =
205 205
206 206 ## alternative return HTTP header for failed authentication. Default HTTP
207 207 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
208 208 ## handling that. Set this variable to 403 to return HTTPForbidden
209 209 auth_ret_code =
210 210
211 211 ## locking return code. When repository is locked return this HTTP code. 2XX
212 212 ## codes don't break the transactions while 4XX codes do
213 213 lock_ret_code = 423
214 214
215 allow_repo_location_change = True
215 216
216 217 ####################################
217 218 ### CELERY CONFIG ####
218 219 ####################################
219 220 use_celery = false
220 221 broker.host = localhost
221 222 broker.vhost = rabbitmqhost
222 223 broker.port = 5672
223 224 broker.user = rabbitmq
224 225 broker.password = qweqwe
225 226
226 227 celery.imports = rhodecode.lib.celerylib.tasks
227 228
228 229 celery.result.backend = amqp
229 230 celery.result.dburi = amqp://
230 231 celery.result.serialier = json
231 232
232 233 #celery.send.task.error.emails = true
233 234 #celery.amqp.task.result.expires = 18000
234 235
235 236 celeryd.concurrency = 2
236 237 #celeryd.log.file = celeryd.log
237 238 celeryd.log.level = debug
238 239 celeryd.max.tasks.per.child = 1
239 240
240 241 ## tasks will never be sent to the queue, but executed locally instead.
241 242 celery.always.eager = false
242 243
243 244 ####################################
244 245 ### BEAKER CACHE ####
245 246 ####################################
246 247 beaker.cache.data_dir=%(here)s/data/cache/data
247 248 beaker.cache.lock_dir=%(here)s/data/cache/lock
248 249
249 250 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
250 251
251 252 beaker.cache.super_short_term.type=memory
252 253 beaker.cache.super_short_term.expire=10
253 254 beaker.cache.super_short_term.key_length = 256
254 255
255 256 beaker.cache.short_term.type=memory
256 257 beaker.cache.short_term.expire=60
257 258 beaker.cache.short_term.key_length = 256
258 259
259 260 beaker.cache.long_term.type=memory
260 261 beaker.cache.long_term.expire=36000
261 262 beaker.cache.long_term.key_length = 256
262 263
263 264 beaker.cache.sql_cache_short.type=memory
264 265 beaker.cache.sql_cache_short.expire=10
265 266 beaker.cache.sql_cache_short.key_length = 256
266 267
267 268 beaker.cache.sql_cache_med.type=memory
268 269 beaker.cache.sql_cache_med.expire=360
269 270 beaker.cache.sql_cache_med.key_length = 256
270 271
271 272 beaker.cache.sql_cache_long.type=file
272 273 beaker.cache.sql_cache_long.expire=3600
273 274 beaker.cache.sql_cache_long.key_length = 256
274 275
275 276 ####################################
276 277 ### BEAKER SESSION ####
277 278 ####################################
278 279 ## Type of storage used for the session, current types are
279 280 ## dbm, file, memcached, database, and memory.
280 281 ## The storage uses the Container API
281 282 ## that is also used by the cache system.
282 283
283 284 ## db session ##
284 285 #beaker.session.type = ext:database
285 286 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
286 287 #beaker.session.table_name = db_session
287 288
288 289 ## encrypted cookie client side session, good for many instances ##
289 290 #beaker.session.type = cookie
290 291
291 292 ## file based cookies (default) ##
292 293 #beaker.session.type = file
293 294
294 295
295 296 beaker.session.key = rhodecode
296 297 ## secure cookie requires AES python libraries
297 298 #beaker.session.encrypt_key = <key_for_encryption>
298 299 #beaker.session.validate_key = <validation_key>
299 300
300 301 ## sets session as invalid if it haven't been accessed for given amount of time
301 302 beaker.session.timeout = 2592000
302 303 beaker.session.httponly = true
303 304 #beaker.session.cookie_path = /<your-prefix>
304 305
305 306 ## uncomment for https secure cookie
306 307 beaker.session.secure = false
307 308
308 309 ## auto save the session to not to use .save()
309 310 beaker.session.auto = False
310 311
311 312 ## default cookie expiration time in seconds `true` expire at browser close ##
312 313 #beaker.session.cookie_expires = 3600
313 314
314 315
315 316 ############################
316 317 ## ERROR HANDLING SYSTEMS ##
317 318 ############################
318 319
319 320 ####################
320 321 ### [errormator] ###
321 322 ####################
322 323
323 324 ## Errormator is tailored to work with RhodeCode, see
324 325 ## http://errormator.com for details how to obtain an account
325 326 ## you must install python package `errormator_client` to make it work
326 327
327 328 ## errormator enabled
328 329 errormator = false
329 330
330 331 errormator.server_url = https://api.errormator.com
331 332 errormator.api_key = YOUR_API_KEY
332 333
333 334 ## TWEAK AMOUNT OF INFO SENT HERE
334 335
335 336 ## enables 404 error logging (default False)
336 337 errormator.report_404 = false
337 338
338 339 ## time in seconds after request is considered being slow (default 1)
339 340 errormator.slow_request_time = 1
340 341
341 342 ## record slow requests in application
342 343 ## (needs to be enabled for slow datastore recording and time tracking)
343 344 errormator.slow_requests = true
344 345
345 346 ## enable hooking to application loggers
346 347 # errormator.logging = true
347 348
348 349 ## minimum log level for log capture
349 350 # errormator.logging.level = WARNING
350 351
351 352 ## send logs only from erroneous/slow requests
352 353 ## (saves API quota for intensive logging)
353 354 errormator.logging_on_error = false
354 355
355 356 ## list of additonal keywords that should be grabbed from environ object
356 357 ## can be string with comma separated list of words in lowercase
357 358 ## (by default client will always send following info:
358 359 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
359 360 ## start with HTTP* this list be extended with additional keywords here
360 361 errormator.environ_keys_whitelist =
361 362
362 363
363 364 ## list of keywords that should be blanked from request object
364 365 ## can be string with comma separated list of words in lowercase
365 366 ## (by default client will always blank keys that contain following words
366 367 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
367 368 ## this list be extended with additional keywords set here
368 369 errormator.request_keys_blacklist =
369 370
370 371
371 372 ## list of namespaces that should be ignores when gathering log entries
372 373 ## can be string with comma separated list of namespaces
373 374 ## (by default the client ignores own entries: errormator_client.client)
374 375 errormator.log_namespace_blacklist =
375 376
376 377
377 378 ################
378 379 ### [sentry] ###
379 380 ################
380 381
381 382 ## sentry is a alternative open source error aggregator
382 383 ## you must install python packages `sentry` and `raven` to enable
383 384
384 385 sentry.dsn = YOUR_DNS
385 386 sentry.servers =
386 387 sentry.name =
387 388 sentry.key =
388 389 sentry.public_key =
389 390 sentry.secret_key =
390 391 sentry.project =
391 392 sentry.site =
392 393 sentry.include_paths =
393 394 sentry.exclude_paths =
394 395
395 396
396 397 ################################################################################
397 398 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
398 399 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
399 400 ## execute malicious code after an exception is raised. ##
400 401 ################################################################################
401 402 set debug = false
402 403
403 404 ##################################
404 405 ### LOGVIEW CONFIG ###
405 406 ##################################
406 407 logview.sqlalchemy = #faa
407 408 logview.pylons.templating = #bfb
408 409 logview.pylons.util = #eee
409 410
410 411 #########################################################
411 412 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
412 413 #########################################################
413 414 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
414 415 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
415 416 sqlalchemy.db1.echo = false
416 417 sqlalchemy.db1.pool_recycle = 3600
417 418 sqlalchemy.db1.convert_unicode = true
418 419
419 420 ################################
420 421 ### LOGGING CONFIGURATION ####
421 422 ################################
422 423 [loggers]
423 424 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
424 425
425 426 [handlers]
426 427 keys = console, console_sql
427 428
428 429 [formatters]
429 430 keys = generic, color_formatter, color_formatter_sql
430 431
431 432 #############
432 433 ## LOGGERS ##
433 434 #############
434 435 [logger_root]
435 436 level = NOTSET
436 437 handlers = console
437 438
438 439 [logger_routes]
439 440 level = DEBUG
440 441 handlers =
441 442 qualname = routes.middleware
442 443 ## "level = DEBUG" logs the route matched and routing variables.
443 444 propagate = 1
444 445
445 446 [logger_beaker]
446 447 level = DEBUG
447 448 handlers =
448 449 qualname = beaker.container
449 450 propagate = 1
450 451
451 452 [logger_templates]
452 453 level = INFO
453 454 handlers =
454 455 qualname = pylons.templating
455 456 propagate = 1
456 457
457 458 [logger_rhodecode]
458 459 level = DEBUG
459 460 handlers =
460 461 qualname = rhodecode
461 462 propagate = 1
462 463
463 464 [logger_sqlalchemy]
464 465 level = INFO
465 466 handlers = console_sql
466 467 qualname = sqlalchemy.engine
467 468 propagate = 0
468 469
469 470 [logger_whoosh_indexer]
470 471 level = DEBUG
471 472 handlers =
472 473 qualname = whoosh_indexer
473 474 propagate = 1
474 475
475 476 ##############
476 477 ## HANDLERS ##
477 478 ##############
478 479
479 480 [handler_console]
480 481 class = StreamHandler
481 482 args = (sys.stderr,)
482 483 level = INFO
483 484 formatter = generic
484 485
485 486 [handler_console_sql]
486 487 class = StreamHandler
487 488 args = (sys.stderr,)
488 489 level = WARN
489 490 formatter = generic
490 491
491 492 ################
492 493 ## FORMATTERS ##
493 494 ################
494 495
495 496 [formatter_generic]
496 497 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
497 498 datefmt = %Y-%m-%d %H:%M:%S
498 499
499 500 [formatter_color_formatter]
500 501 class=rhodecode.lib.colored_formatter.ColorFormatter
501 502 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
502 503 datefmt = %Y-%m-%d %H:%M:%S
503 504
504 505 [formatter_color_formatter_sql]
505 506 class=rhodecode.lib.colored_formatter.ColorFormatterSql
506 507 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 508 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,517 +1,518 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. Don't change that to more than 1
54 54 #workers = 1
55 55 ## process name
56 56 #proc_name = rhodecode
57 57 ## type of worker class, one of sync, eventlet, gevent, tornado
58 58 ## recommended for bigger setup is using of of other than sync one
59 59 #worker-class = sync
60 60 #max-requests = 5
61 61
62 62 ## COMMON ##
63 63 host = 127.0.0.1
64 64 port = 5000
65 65
66 66 ## prefix middleware for rc
67 67 #[filter:proxy-prefix]
68 68 #use = egg:PasteDeploy#prefix
69 69 #prefix = /<your-prefix>
70 70
71 71 [app:main]
72 72 use = egg:rhodecode
73 73 ## enable proxy prefix middleware
74 74 #filter-with = proxy-prefix
75 75
76 76 full_stack = true
77 77 static_files = true
78 78 ## Optional Languages
79 79 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
80 80 lang = en
81 81 cache_dir = %(here)s/data
82 82 index_dir = %(here)s/data/index
83 83
84 84 ## perform a full repository scan on each server start, this should be
85 85 ## set to false after first startup, to allow faster server restarts.
86 86 initial_repo_scan = true
87 87
88 88 ## uncomment and set this path to use archive download cache
89 89 #archive_cache_dir = /tmp/tarballcache
90 90
91 91 ## change this to unique ID for security
92 92 app_instance_uuid = ${app_instance_uuid}
93 93
94 94 ## cut off limit for large diffs (size in bytes)
95 95 cut_off_limit = 256000
96 96
97 97 ## use cache version of scm repo everywhere
98 98 vcs_full_cache = true
99 99
100 100 ## force https in RhodeCode, fixes https redirects, assumes it's always https
101 101 force_https = false
102 102
103 103 ## use Strict-Transport-Security headers
104 104 use_htsts = false
105 105
106 106 ## number of commits stats will parse on each iteration
107 107 commit_parse_limit = 25
108 108
109 109 ## use gravatar service to display avatars
110 110 use_gravatar = true
111 111
112 112 ## path to git executable
113 113 git_path = git
114 114
115 115 ## git rev filter option, --all is the default filter, if you need to
116 116 ## hide all refs in changelog switch this to --branches --tags
117 117 git_rev_filter=--all
118 118
119 119 ## RSS feed options
120 120 rss_cut_off_limit = 256000
121 121 rss_items_per_page = 10
122 122 rss_include_diff = false
123 123
124 124 ## options for showing and identifying changesets
125 125 show_sha_length = 12
126 126 show_revision_number = true
127 127
128 128 ## gist URL alias, used to create nicer urls for gist. This should be an
129 129 ## url that does rewrites to _admin/gists/<gistid>.
130 130 ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal
131 131 ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid>
132 132 gist_alias_url =
133 133
134 134 ## white list of API enabled controllers. This allows to add list of
135 135 ## controllers to which access will be enabled by api_key. eg: to enable
136 136 ## api access to raw_files put `FilesController:raw`, to enable access to patches
137 137 ## add `ChangesetController:changeset_patch`. This list should be "," separated
138 138 ## Syntax is <ControllerClass>:<function>. Check debug logs for generated names
139 139 api_access_controllers_whitelist =
140 140
141 141 ## alternative_gravatar_url allows you to use your own avatar server application
142 142 ## the following parts of the URL will be replaced
143 143 ## {email} user email
144 144 ## {md5email} md5 hash of the user email (like at gravatar.com)
145 145 ## {size} size of the image that is expected from the server application
146 146 ## {scheme} http/https from RhodeCode server
147 147 ## {netloc} network location from RhodeCode server
148 148 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
149 149 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
150 150
151 151
152 152 ## container auth options
153 153 container_auth_enabled = false
154 154 proxypass_auth_enabled = false
155 155
156 156 ## default encoding used to convert from and to unicode
157 157 ## can be also a comma seperated list of encoding in case of mixed encodings
158 158 default_encoding = utf8
159 159
160 160 ## overwrite schema of clone url
161 161 ## available vars:
162 162 ## scheme - http/https
163 163 ## user - current user
164 164 ## pass - password
165 165 ## netloc - network location
166 166 ## path - usually repo_name
167 167
168 168 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
169 169
170 170 ## issue tracking mapping for commits messages
171 171 ## comment out issue_pat, issue_server, issue_prefix to enable
172 172
173 173 ## pattern to get the issues from commit messages
174 174 ## default one used here is #<numbers> with a regex passive group for `#`
175 175 ## {id} will be all groups matched from this pattern
176 176
177 177 issue_pat = (?:\s*#)(\d+)
178 178
179 179 ## server url to the issue, each {id} will be replaced with match
180 180 ## fetched from the regex and {repo} is replaced with full repository name
181 181 ## including groups {repo_name} is replaced with just name of repo
182 182
183 183 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
184 184
185 185 ## prefix to add to link to indicate it's an url
186 186 ## #314 will be replaced by <issue_prefix><id>
187 187
188 188 issue_prefix = #
189 189
190 190 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
191 191 ## multiple patterns, to other issues server, wiki or others
192 192 ## below an example how to create a wiki pattern
193 193 # #wiki-some-id -> https://mywiki.com/some-id
194 194
195 195 #issue_pat_wiki = (?:wiki-)(.+)
196 196 #issue_server_link_wiki = https://mywiki.com/{id}
197 197 #issue_prefix_wiki = WIKI-
198 198
199 199
200 200 ## instance-id prefix
201 201 ## a prefix key for this instance used for cache invalidation when running
202 202 ## multiple instances of rhodecode, make sure it's globally unique for
203 203 ## all running rhodecode instances. Leave empty if you don't use it
204 204 instance_id =
205 205
206 206 ## alternative return HTTP header for failed authentication. Default HTTP
207 207 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
208 208 ## handling that. Set this variable to 403 to return HTTPForbidden
209 209 auth_ret_code =
210 210
211 211 ## locking return code. When repository is locked return this HTTP code. 2XX
212 212 ## codes don't break the transactions while 4XX codes do
213 213 lock_ret_code = 423
214 214
215 allow_repo_location_change = True
215 216
216 217 ####################################
217 218 ### CELERY CONFIG ####
218 219 ####################################
219 220 use_celery = false
220 221 broker.host = localhost
221 222 broker.vhost = rabbitmqhost
222 223 broker.port = 5672
223 224 broker.user = rabbitmq
224 225 broker.password = qweqwe
225 226
226 227 celery.imports = rhodecode.lib.celerylib.tasks
227 228
228 229 celery.result.backend = amqp
229 230 celery.result.dburi = amqp://
230 231 celery.result.serialier = json
231 232
232 233 #celery.send.task.error.emails = true
233 234 #celery.amqp.task.result.expires = 18000
234 235
235 236 celeryd.concurrency = 2
236 237 #celeryd.log.file = celeryd.log
237 238 celeryd.log.level = debug
238 239 celeryd.max.tasks.per.child = 1
239 240
240 241 ## tasks will never be sent to the queue, but executed locally instead.
241 242 celery.always.eager = false
242 243
243 244 ####################################
244 245 ### BEAKER CACHE ####
245 246 ####################################
246 247 beaker.cache.data_dir=%(here)s/data/cache/data
247 248 beaker.cache.lock_dir=%(here)s/data/cache/lock
248 249
249 250 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
250 251
251 252 beaker.cache.super_short_term.type=memory
252 253 beaker.cache.super_short_term.expire=10
253 254 beaker.cache.super_short_term.key_length = 256
254 255
255 256 beaker.cache.short_term.type=memory
256 257 beaker.cache.short_term.expire=60
257 258 beaker.cache.short_term.key_length = 256
258 259
259 260 beaker.cache.long_term.type=memory
260 261 beaker.cache.long_term.expire=36000
261 262 beaker.cache.long_term.key_length = 256
262 263
263 264 beaker.cache.sql_cache_short.type=memory
264 265 beaker.cache.sql_cache_short.expire=10
265 266 beaker.cache.sql_cache_short.key_length = 256
266 267
267 268 beaker.cache.sql_cache_med.type=memory
268 269 beaker.cache.sql_cache_med.expire=360
269 270 beaker.cache.sql_cache_med.key_length = 256
270 271
271 272 beaker.cache.sql_cache_long.type=file
272 273 beaker.cache.sql_cache_long.expire=3600
273 274 beaker.cache.sql_cache_long.key_length = 256
274 275
275 276 ####################################
276 277 ### BEAKER SESSION ####
277 278 ####################################
278 279 ## Type of storage used for the session, current types are
279 280 ## dbm, file, memcached, database, and memory.
280 281 ## The storage uses the Container API
281 282 ## that is also used by the cache system.
282 283
283 284 ## db session ##
284 285 #beaker.session.type = ext:database
285 286 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
286 287 #beaker.session.table_name = db_session
287 288
288 289 ## encrypted cookie client side session, good for many instances ##
289 290 #beaker.session.type = cookie
290 291
291 292 ## file based cookies (default) ##
292 293 #beaker.session.type = file
293 294
294 295
295 296 beaker.session.key = rhodecode
296 297 ## secure cookie requires AES python libraries
297 298 #beaker.session.encrypt_key = <key_for_encryption>
298 299 #beaker.session.validate_key = <validation_key>
299 300
300 301 ## sets session as invalid if it haven't been accessed for given amount of time
301 302 beaker.session.timeout = 2592000
302 303 beaker.session.httponly = true
303 304 #beaker.session.cookie_path = /<your-prefix>
304 305
305 306 ## uncomment for https secure cookie
306 307 beaker.session.secure = false
307 308
308 309 ## auto save the session to not to use .save()
309 310 beaker.session.auto = False
310 311
311 312 ## default cookie expiration time in seconds `true` expire at browser close ##
312 313 #beaker.session.cookie_expires = 3600
313 314
314 315
315 316 ############################
316 317 ## ERROR HANDLING SYSTEMS ##
317 318 ############################
318 319
319 320 ####################
320 321 ### [errormator] ###
321 322 ####################
322 323
323 324 ## Errormator is tailored to work with RhodeCode, see
324 325 ## http://errormator.com for details how to obtain an account
325 326 ## you must install python package `errormator_client` to make it work
326 327
327 328 ## errormator enabled
328 329 errormator = false
329 330
330 331 errormator.server_url = https://api.errormator.com
331 332 errormator.api_key = YOUR_API_KEY
332 333
333 334 ## TWEAK AMOUNT OF INFO SENT HERE
334 335
335 336 ## enables 404 error logging (default False)
336 337 errormator.report_404 = false
337 338
338 339 ## time in seconds after request is considered being slow (default 1)
339 340 errormator.slow_request_time = 1
340 341
341 342 ## record slow requests in application
342 343 ## (needs to be enabled for slow datastore recording and time tracking)
343 344 errormator.slow_requests = true
344 345
345 346 ## enable hooking to application loggers
346 347 # errormator.logging = true
347 348
348 349 ## minimum log level for log capture
349 350 # errormator.logging.level = WARNING
350 351
351 352 ## send logs only from erroneous/slow requests
352 353 ## (saves API quota for intensive logging)
353 354 errormator.logging_on_error = false
354 355
355 356 ## list of additonal keywords that should be grabbed from environ object
356 357 ## can be string with comma separated list of words in lowercase
357 358 ## (by default client will always send following info:
358 359 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
359 360 ## start with HTTP* this list be extended with additional keywords here
360 361 errormator.environ_keys_whitelist =
361 362
362 363
363 364 ## list of keywords that should be blanked from request object
364 365 ## can be string with comma separated list of words in lowercase
365 366 ## (by default client will always blank keys that contain following words
366 367 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
367 368 ## this list be extended with additional keywords set here
368 369 errormator.request_keys_blacklist =
369 370
370 371
371 372 ## list of namespaces that should be ignores when gathering log entries
372 373 ## can be string with comma separated list of namespaces
373 374 ## (by default the client ignores own entries: errormator_client.client)
374 375 errormator.log_namespace_blacklist =
375 376
376 377
377 378 ################
378 379 ### [sentry] ###
379 380 ################
380 381
381 382 ## sentry is a alternative open source error aggregator
382 383 ## you must install python packages `sentry` and `raven` to enable
383 384
384 385 sentry.dsn = YOUR_DNS
385 386 sentry.servers =
386 387 sentry.name =
387 388 sentry.key =
388 389 sentry.public_key =
389 390 sentry.secret_key =
390 391 sentry.project =
391 392 sentry.site =
392 393 sentry.include_paths =
393 394 sentry.exclude_paths =
394 395
395 396
396 397 ################################################################################
397 398 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
398 399 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
399 400 ## execute malicious code after an exception is raised. ##
400 401 ################################################################################
401 402 set debug = false
402 403
403 404 ##################################
404 405 ### LOGVIEW CONFIG ###
405 406 ##################################
406 407 logview.sqlalchemy = #faa
407 408 logview.pylons.templating = #bfb
408 409 logview.pylons.util = #eee
409 410
410 411 #########################################################
411 412 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
412 413 #########################################################
413 414
414 415 # SQLITE [default]
415 416 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
416 417
417 418 # POSTGRESQL
418 419 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
419 420
420 421 # MySQL
421 422 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
422 423
423 424 # see sqlalchemy docs for others
424 425
425 426 sqlalchemy.db1.echo = false
426 427 sqlalchemy.db1.pool_recycle = 3600
427 428 sqlalchemy.db1.convert_unicode = true
428 429
429 430 ################################
430 431 ### LOGGING CONFIGURATION ####
431 432 ################################
432 433 [loggers]
433 434 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
434 435
435 436 [handlers]
436 437 keys = console, console_sql
437 438
438 439 [formatters]
439 440 keys = generic, color_formatter, color_formatter_sql
440 441
441 442 #############
442 443 ## LOGGERS ##
443 444 #############
444 445 [logger_root]
445 446 level = NOTSET
446 447 handlers = console
447 448
448 449 [logger_routes]
449 450 level = DEBUG
450 451 handlers =
451 452 qualname = routes.middleware
452 453 ## "level = DEBUG" logs the route matched and routing variables.
453 454 propagate = 1
454 455
455 456 [logger_beaker]
456 457 level = DEBUG
457 458 handlers =
458 459 qualname = beaker.container
459 460 propagate = 1
460 461
461 462 [logger_templates]
462 463 level = INFO
463 464 handlers =
464 465 qualname = pylons.templating
465 466 propagate = 1
466 467
467 468 [logger_rhodecode]
468 469 level = DEBUG
469 470 handlers =
470 471 qualname = rhodecode
471 472 propagate = 1
472 473
473 474 [logger_sqlalchemy]
474 475 level = INFO
475 476 handlers = console_sql
476 477 qualname = sqlalchemy.engine
477 478 propagate = 0
478 479
479 480 [logger_whoosh_indexer]
480 481 level = DEBUG
481 482 handlers =
482 483 qualname = whoosh_indexer
483 484 propagate = 1
484 485
485 486 ##############
486 487 ## HANDLERS ##
487 488 ##############
488 489
489 490 [handler_console]
490 491 class = StreamHandler
491 492 args = (sys.stderr,)
492 493 level = INFO
493 494 formatter = generic
494 495
495 496 [handler_console_sql]
496 497 class = StreamHandler
497 498 args = (sys.stderr,)
498 499 level = WARN
499 500 formatter = generic
500 501
501 502 ################
502 503 ## FORMATTERS ##
503 504 ################
504 505
505 506 [formatter_generic]
506 507 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
507 508 datefmt = %Y-%m-%d %H:%M:%S
508 509
509 510 [formatter_color_formatter]
510 511 class=rhodecode.lib.colored_formatter.ColorFormatter
511 512 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
512 513 datefmt = %Y-%m-%d %H:%M:%S
513 514
514 515 [formatter_color_formatter_sql]
515 516 class=rhodecode.lib.colored_formatter.ColorFormatterSql
516 517 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
517 518 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,519 +1,519 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 log.debug('Rescanning directories with destroy=%s' % rm_obsolete)
116 116 initial = ScmModel().repo_scan()
117 117 log.debug('invalidating all repositories')
118 118 for repo_name in initial.keys():
119 119 ScmModel().mark_for_invalidation(repo_name)
120 120
121 121 added, removed = repo2db_mapper(initial, rm_obsolete)
122 122 _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
123 123 h.flash(_('Repositories successfully '
124 124 'rescanned added: %s ; removed: %s') %
125 125 (_repr(added), _repr(removed)),
126 126 category='success')
127 127
128 128 if setting_id == 'whoosh':
129 129 repo_location = self._get_hg_ui_settings()['paths_root_path']
130 130 full_index = request.POST.get('full_index', False)
131 131 run_task(tasks.whoosh_index, repo_location, full_index)
132 132 h.flash(_('Whoosh reindex task scheduled'), category='success')
133 133
134 134 if setting_id == 'global':
135 135
136 136 application_form = ApplicationSettingsForm()()
137 137 try:
138 138 form_result = application_form.to_python(dict(request.POST))
139 139 except formencode.Invalid, errors:
140 140 return htmlfill.render(
141 141 render('admin/settings/settings.html'),
142 142 defaults=errors.value,
143 143 errors=errors.error_dict or {},
144 144 prefix_error=False,
145 145 encoding="UTF-8"
146 146 )
147 147
148 148 try:
149 149 sett1 = RhodeCodeSetting.get_by_name_or_create('title')
150 150 sett1.app_settings_value = form_result['rhodecode_title']
151 151 Session().add(sett1)
152 152
153 153 sett2 = RhodeCodeSetting.get_by_name_or_create('realm')
154 154 sett2.app_settings_value = form_result['rhodecode_realm']
155 155 Session().add(sett2)
156 156
157 157 sett3 = RhodeCodeSetting.get_by_name_or_create('ga_code')
158 158 sett3.app_settings_value = form_result['rhodecode_ga_code']
159 159 Session().add(sett3)
160 160
161 161 Session().commit()
162 162 set_rhodecode_config(config)
163 163 h.flash(_('Updated application settings'), category='success')
164 164
165 165 except Exception:
166 166 log.error(traceback.format_exc())
167 167 h.flash(_('Error occurred during updating '
168 168 'application settings'),
169 169 category='error')
170 170
171 171 if setting_id == 'visual':
172 172
173 173 application_form = ApplicationVisualisationForm()()
174 174 try:
175 175 form_result = application_form.to_python(dict(request.POST))
176 176 except formencode.Invalid, errors:
177 177 return htmlfill.render(
178 178 render('admin/settings/settings.html'),
179 179 defaults=errors.value,
180 180 errors=errors.error_dict or {},
181 181 prefix_error=False,
182 182 encoding="UTF-8"
183 183 )
184 184
185 185 try:
186 186 #TODO: rewrite this to something less ugly
187 187 sett1 = RhodeCodeSetting.get_by_name_or_create('show_public_icon')
188 188 sett1.app_settings_value = \
189 189 form_result['rhodecode_show_public_icon']
190 190 Session().add(sett1)
191 191
192 192 sett2 = RhodeCodeSetting.get_by_name_or_create('show_private_icon')
193 193 sett2.app_settings_value = \
194 194 form_result['rhodecode_show_private_icon']
195 195 Session().add(sett2)
196 196
197 197 sett3 = RhodeCodeSetting.get_by_name_or_create('stylify_metatags')
198 198 sett3.app_settings_value = \
199 199 form_result['rhodecode_stylify_metatags']
200 200 Session().add(sett3)
201 201
202 202 sett4 = RhodeCodeSetting.get_by_name_or_create('repository_fields')
203 203 sett4.app_settings_value = \
204 204 form_result['rhodecode_repository_fields']
205 205 Session().add(sett4)
206 206
207 207 sett5 = RhodeCodeSetting.get_by_name_or_create('dashboard_items')
208 208 sett5.app_settings_value = \
209 209 form_result['rhodecode_dashboard_items']
210 210 Session().add(sett5)
211 211
212 212 sett6 = RhodeCodeSetting.get_by_name_or_create('show_version')
213 213 sett6.app_settings_value = \
214 214 form_result['rhodecode_show_version']
215 215 Session().add(sett6)
216 216
217 217 Session().commit()
218 218 set_rhodecode_config(config)
219 219 h.flash(_('Updated visualisation settings'),
220 220 category='success')
221 221
222 222 except Exception:
223 223 log.error(traceback.format_exc())
224 224 h.flash(_('Error occurred during updating '
225 225 'visualisation settings'),
226 226 category='error')
227 227
228 228 if setting_id == 'vcs':
229 229 application_form = ApplicationUiSettingsForm()()
230 230 try:
231 231 form_result = application_form.to_python(dict(request.POST))
232 232 except formencode.Invalid, errors:
233 233 return htmlfill.render(
234 234 render('admin/settings/settings.html'),
235 235 defaults=errors.value,
236 236 errors=errors.error_dict or {},
237 237 prefix_error=False,
238 238 encoding="UTF-8"
239 239 )
240 240
241 241 try:
242 242 sett = RhodeCodeUi.get_by_key('push_ssl')
243 243 sett.ui_value = form_result['web_push_ssl']
244 244 Session().add(sett)
245
245 if c.visual.allow_repo_location_change:
246 246 sett = RhodeCodeUi.get_by_key('/')
247 247 sett.ui_value = form_result['paths_root_path']
248 248 Session().add(sett)
249 249
250 250 #HOOKS
251 251 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE)
252 252 sett.ui_active = form_result['hooks_changegroup_update']
253 253 Session().add(sett)
254 254
255 255 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_REPO_SIZE)
256 256 sett.ui_active = form_result['hooks_changegroup_repo_size']
257 257 Session().add(sett)
258 258
259 259 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PUSH)
260 260 sett.ui_active = form_result['hooks_changegroup_push_logger']
261 261 Session().add(sett)
262 262
263 263 sett = RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_PULL)
264 264 sett.ui_active = form_result['hooks_outgoing_pull_logger']
265 265
266 266 Session().add(sett)
267 267
268 268 ## EXTENSIONS
269 269 sett = RhodeCodeUi.get_by_key('largefiles')
270 270 if not sett:
271 271 #make one if it's not there !
272 272 sett = RhodeCodeUi()
273 273 sett.ui_key = 'largefiles'
274 274 sett.ui_section = 'extensions'
275 275 sett.ui_active = form_result['extensions_largefiles']
276 276 Session().add(sett)
277 277
278 278 sett = RhodeCodeUi.get_by_key('hgsubversion')
279 279 if not sett:
280 280 #make one if it's not there !
281 281 sett = RhodeCodeUi()
282 282 sett.ui_key = 'hgsubversion'
283 283 sett.ui_section = 'extensions'
284 284
285 285 sett.ui_active = form_result['extensions_hgsubversion']
286 286 Session().add(sett)
287 287
288 288 # sett = RhodeCodeUi.get_by_key('hggit')
289 289 # if not sett:
290 290 # #make one if it's not there !
291 291 # sett = RhodeCodeUi()
292 292 # sett.ui_key = 'hggit'
293 293 # sett.ui_section = 'extensions'
294 294 #
295 295 # sett.ui_active = form_result['extensions_hggit']
296 296 # Session().add(sett)
297 297
298 298 Session().commit()
299 299
300 300 h.flash(_('Updated VCS settings'), category='success')
301 301
302 302 except Exception:
303 303 log.error(traceback.format_exc())
304 304 h.flash(_('Error occurred during updating '
305 305 'application settings'), category='error')
306 306
307 307 if setting_id == 'hooks':
308 308 ui_key = request.POST.get('new_hook_ui_key')
309 309 ui_value = request.POST.get('new_hook_ui_value')
310 310 try:
311 311
312 312 if ui_value and ui_key:
313 313 RhodeCodeUi.create_or_update_hook(ui_key, ui_value)
314 314 h.flash(_('Added new hook'),
315 315 category='success')
316 316
317 317 # check for edits
318 318 update = False
319 319 _d = request.POST.dict_of_lists()
320 320 for k, v in zip(_d.get('hook_ui_key', []),
321 321 _d.get('hook_ui_value_new', [])):
322 322 RhodeCodeUi.create_or_update_hook(k, v)
323 323 update = True
324 324
325 325 if update:
326 326 h.flash(_('Updated hooks'), category='success')
327 327 Session().commit()
328 328 except Exception:
329 329 log.error(traceback.format_exc())
330 330 h.flash(_('Error occurred during hook creation'),
331 331 category='error')
332 332
333 333 return redirect(url('admin_edit_setting', setting_id='hooks'))
334 334
335 335 if setting_id == 'email':
336 336 test_email = request.POST.get('test_email')
337 337 test_email_subj = 'RhodeCode TestEmail'
338 338 test_email_body = 'RhodeCode Email test'
339 339
340 340 test_email_html_body = EmailNotificationModel()\
341 341 .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
342 342 body=test_email_body)
343 343
344 344 recipients = [test_email] if test_email else None
345 345
346 346 run_task(tasks.send_email, recipients, test_email_subj,
347 347 test_email_body, test_email_html_body)
348 348
349 349 h.flash(_('Email task created'), category='success')
350 350 return redirect(url('admin_settings'))
351 351
352 352 @HasPermissionAllDecorator('hg.admin')
353 353 def delete(self, setting_id):
354 354 """DELETE /admin/settings/setting_id: Delete an existing item"""
355 355 # Forms posted to this method should contain a hidden field:
356 356 # <input type="hidden" name="_method" value="DELETE" />
357 357 # Or using helpers:
358 358 # h.form(url('admin_setting', setting_id=ID),
359 359 # method='delete')
360 360 # url('admin_setting', setting_id=ID)
361 361 if setting_id == 'hooks':
362 362 hook_id = request.POST.get('hook_id')
363 363 RhodeCodeUi.delete(hook_id)
364 364 Session().commit()
365 365
366 366 @HasPermissionAllDecorator('hg.admin')
367 367 def show(self, setting_id, format='html'):
368 368 """
369 369 GET /admin/settings/setting_id: Show a specific item"""
370 370 # url('admin_setting', setting_id=ID)
371 371
372 372 @HasPermissionAllDecorator('hg.admin')
373 373 def edit(self, setting_id, format='html'):
374 374 """
375 375 GET /admin/settings/setting_id/edit: Form to
376 376 edit an existing item"""
377 377 # url('admin_edit_setting', setting_id=ID)
378 378
379 379 c.hooks = RhodeCodeUi.get_builtin_hooks()
380 380 c.custom_hooks = RhodeCodeUi.get_custom_hooks()
381 381
382 382 return htmlfill.render(
383 383 render('admin/settings/hooks.html'),
384 384 defaults={},
385 385 encoding="UTF-8",
386 386 force_defaults=False
387 387 )
388 388
389 389 def _load_my_repos_data(self):
390 390 repos_list = Session().query(Repository)\
391 391 .filter(Repository.user_id ==
392 392 self.rhodecode_user.user_id)\
393 393 .order_by(func.lower(Repository.repo_name)).all()
394 394
395 395 repos_data = RepoModel().get_repos_as_dict(repos_list=repos_list,
396 396 admin=True)
397 397 #json used to render the grid
398 398 return json.dumps(repos_data)
399 399
400 400 @NotAnonymous()
401 401 def my_account(self):
402 402 """
403 403 GET /_admin/my_account Displays info about my account
404 404 """
405 405 # url('admin_settings_my_account')
406 406
407 407 c.user = User.get(self.rhodecode_user.user_id)
408 408 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
409 409 ip_addr=self.ip_addr)
410 410 c.ldap_dn = c.user.ldap_dn
411 411
412 412 if c.user.username == 'default':
413 413 h.flash(_("You can't edit this user since it's"
414 414 " crucial for entire application"), category='warning')
415 415 return redirect(url('users'))
416 416
417 417 #json used to render the grid
418 418 c.data = self._load_my_repos_data()
419 419
420 420 defaults = c.user.get_dict()
421 421
422 422 c.form = htmlfill.render(
423 423 render('admin/users/user_edit_my_account_form.html'),
424 424 defaults=defaults,
425 425 encoding="UTF-8",
426 426 force_defaults=False
427 427 )
428 428 return render('admin/users/user_edit_my_account.html')
429 429
430 430 @NotAnonymous()
431 431 def my_account_update(self):
432 432 """PUT /_admin/my_account_update: Update an existing item"""
433 433 # Forms posted to this method should contain a hidden field:
434 434 # <input type="hidden" name="_method" value="PUT" />
435 435 # Or using helpers:
436 436 # h.form(url('admin_settings_my_account_update'),
437 437 # method='put')
438 438 # url('admin_settings_my_account_update', id=ID)
439 439 uid = self.rhodecode_user.user_id
440 440 c.user = User.get(self.rhodecode_user.user_id)
441 441 c.perm_user = AuthUser(user_id=self.rhodecode_user.user_id,
442 442 ip_addr=self.ip_addr)
443 443 c.ldap_dn = c.user.ldap_dn
444 444 email = self.rhodecode_user.email
445 445 _form = UserForm(edit=True,
446 446 old_data={'user_id': uid, 'email': email})()
447 447 form_result = {}
448 448 try:
449 449 form_result = _form.to_python(dict(request.POST))
450 450 skip_attrs = ['admin', 'active'] # skip attr for my account
451 451 if c.ldap_dn:
452 452 #forbid updating username for ldap accounts
453 453 skip_attrs.append('username')
454 454 UserModel().update(uid, form_result, skip_attrs=skip_attrs)
455 455 h.flash(_('Your account was updated successfully'),
456 456 category='success')
457 457 Session().commit()
458 458 except formencode.Invalid, errors:
459 459 #json used to render the grid
460 460 c.data = self._load_my_repos_data()
461 461 c.form = htmlfill.render(
462 462 render('admin/users/user_edit_my_account_form.html'),
463 463 defaults=errors.value,
464 464 errors=errors.error_dict or {},
465 465 prefix_error=False,
466 466 encoding="UTF-8")
467 467 return render('admin/users/user_edit_my_account.html')
468 468 except Exception:
469 469 log.error(traceback.format_exc())
470 470 h.flash(_('Error occurred during update of user %s') \
471 471 % form_result.get('username'), category='error')
472 472
473 473 return redirect(url('my_account'))
474 474
475 475 @NotAnonymous()
476 476 def my_account_my_pullrequests(self):
477 477 c.show_closed = request.GET.get('pr_show_closed')
478 478
479 479 def _filter(pr):
480 480 s = sorted(pr, key=lambda o: o.created_on, reverse=True)
481 481 if not c.show_closed:
482 482 s = filter(lambda p: p.status != PullRequest.STATUS_CLOSED, s)
483 483 return s
484 484
485 485 c.my_pull_requests = _filter(PullRequest.query()\
486 486 .filter(PullRequest.user_id ==
487 487 self.rhodecode_user.user_id)\
488 488 .all())
489 489
490 490 c.participate_in_pull_requests = _filter([
491 491 x.pull_request for x in PullRequestReviewers.query()\
492 492 .filter(PullRequestReviewers.user_id ==
493 493 self.rhodecode_user.user_id).all()])
494 494
495 495 return render('admin/users/user_edit_my_account_pullrequests.html')
496 496
497 497 def _get_hg_ui_settings(self):
498 498 ret = RhodeCodeUi.query().all()
499 499
500 500 if not ret:
501 501 raise Exception('Could not get application ui settings !')
502 502 settings = {}
503 503 for each in ret:
504 504 k = each.ui_key
505 505 v = each.ui_value
506 506 if k == '/':
507 507 k = 'root_path'
508 508
509 509 if k == 'push_ssl':
510 510 v = str2bool(v)
511 511
512 512 if k.find('.') != -1:
513 513 k = k.replace('.', '_')
514 514
515 515 if each.ui_section in ['hooks', 'extensions']:
516 516 v = each.ui_active
517 517
518 518 settings[each.ui_section + '_' + k] = v
519 519 return settings
@@ -1,347 +1,348 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 mutliple 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.use_gravatar = str2bool(config.get('use_gravatar'))
266 266 c.ga_code = config.get('rhodecode_ga_code')
267 267 # Visual options
268 268 c.visual = AttributeDict({})
269 269 rc_config = RhodeCodeSetting.get_app_settings()
270 270 ## DB stored
271 271 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
272 272 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
273 273 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
274 274 c.visual.dashboard_items = safe_int(rc_config.get('rhodecode_dashboard_items', 100))
275 275 c.visual.repository_fields = str2bool(rc_config.get('rhodecode_repository_fields'))
276 276 c.visual.show_version = str2bool(rc_config.get('rhodecode_show_version'))
277 277
278 278 ## INI stored
279 279 self.cut_off_limit = int(config.get('cut_off_limit'))
280 c.visual.allow_repo_location_change = str2bool(config.get('allow_repo_location_change', True))
280 281
281 282 c.repo_name = get_repo_slug(request) # can be empty
282 283 c.backends = BACKENDS.keys()
283 284 c.unread_notifications = NotificationModel()\
284 285 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
285 286 self.sa = meta.Session
286 287 self.scm_model = ScmModel(self.sa)
287 288
288 289 def __call__(self, environ, start_response):
289 290 """Invoke the Controller"""
290 291 # WSGIController.__call__ dispatches to the Controller method
291 292 # the request is routed to. This routing information is
292 293 # available in environ['pylons.routes_dict']
293 294 try:
294 295 self.ip_addr = _get_ip_addr(environ)
295 296 # make sure that we update permissions each time we call controller
296 297 api_key = request.GET.get('api_key')
297 298 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
298 299 user_id = cookie_store.get('user_id', None)
299 300 username = get_container_username(environ, config)
300 301 auth_user = AuthUser(user_id, api_key, username, self.ip_addr)
301 302 request.user = auth_user
302 303 self.rhodecode_user = c.rhodecode_user = auth_user
303 304 if not self.rhodecode_user.is_authenticated and \
304 305 self.rhodecode_user.user_id is not None:
305 306 self.rhodecode_user.set_authenticated(
306 307 cookie_store.get('is_authenticated')
307 308 )
308 309 log.info('IP: %s User: %s accessed %s' % (
309 310 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
310 311 )
311 312 return WSGIController.__call__(self, environ, start_response)
312 313 finally:
313 314 meta.Session.remove()
314 315
315 316
316 317 class BaseRepoController(BaseController):
317 318 """
318 319 Base class for controllers responsible for loading all needed data for
319 320 repository loaded items are
320 321
321 322 c.rhodecode_repo: instance of scm repository
322 323 c.rhodecode_db_repo: instance of db
323 324 c.repository_followers: number of followers
324 325 c.repository_forks: number of forks
325 326 c.repository_following: weather the current user is following the current repo
326 327 """
327 328
328 329 def __before__(self):
329 330 super(BaseRepoController, self).__before__()
330 331 if c.repo_name:
331 332
332 333 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
333 334 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
334 335 # update last change according to VCS data
335 336 dbr.update_changeset_cache(dbr.get_changeset())
336 337 if c.rhodecode_repo is None:
337 338 log.error('%s this repository is present in database but it '
338 339 'cannot be created as an scm instance', c.repo_name)
339 340
340 341 redirect(url('home'))
341 342
342 343 # some globals counter for menu
343 344 c.repository_followers = self.scm_model.get_followers(dbr)
344 345 c.repository_forks = self.scm_model.get_forks(dbr)
345 346 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
346 347 c.repository_following = self.scm_model.is_following_repo(c.repo_name,
347 348 self.rhodecode_user.user_id)
@@ -1,356 +1,358 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'))}
10 10 &raquo;
11 11 ${_('Settings')}
12 12 </%def>
13 13
14 14 <%def name="page_nav()">
15 15 ${self.menu('admin')}
16 16 </%def>
17 17
18 18 <%def name="main()">
19 19 <div class="box">
20 20 <!-- box / title -->
21 21 <div class="title">
22 22 ${self.breadcrumbs()}
23 23 </div>
24 24 <!-- end box / title -->
25 25
26 26 <h3>${_('Remap and rescan repositories')}</h3>
27 27 ${h.form(url('admin_setting', setting_id='mapping'),method='put')}
28 28 <div class="form">
29 29 <!-- fields -->
30 30
31 31 <div class="fields">
32 32 <div class="field">
33 33 <div class="label label-checkbox">
34 34 <label for="destroy">${_('Rescan option')}:</label>
35 35 </div>
36 36 <div class="checkboxes">
37 37 <div class="checkbox">
38 38 ${h.checkbox('destroy',True)}
39 39 <label for="destroy">
40 40 <span class="tooltip" title="${h.tooltip(_('In case a repository was deleted from filesystem and there are leftovers in the database check this option to scan obsolete data in database and remove it.'))}">
41 41 ${_('Destroy old data')}</span> </label>
42 42 </div>
43 43 <span class="help-block">${_('Rescan repositories location for new repositories. Also deletes obsolete if `destroy` flag is checked ')}</span>
44 44 </div>
45 45 </div>
46 46
47 47 <div class="buttons">
48 48 ${h.submit('rescan',_('Rescan repositories'),class_="ui-btn large")}
49 49 </div>
50 50 </div>
51 51 </div>
52 52 ${h.end_form()}
53 53
54 54 <h3>${_('Whoosh indexing')}</h3>
55 55 ${h.form(url('admin_setting', setting_id='whoosh'),method='put')}
56 56 <div class="form">
57 57 <!-- fields -->
58 58
59 59 <div class="fields">
60 60 <div class="field">
61 61 <div class="label label-checkbox">
62 62 <label>${_('Index build option')}:</label>
63 63 </div>
64 64 <div class="checkboxes">
65 65 <div class="checkbox">
66 66 ${h.checkbox('full_index',True)}
67 67 <label for="full_index">${_('Build from scratch')}</label>
68 68 </div>
69 69 </div>
70 70 </div>
71 71
72 72 <div class="buttons">
73 73 ${h.submit('reindex',_('Reindex'),class_="ui-btn large")}
74 74 </div>
75 75 </div>
76 76 </div>
77 77 ${h.end_form()}
78 78
79 79 <h3>${_('Global application settings')}</h3>
80 80 ${h.form(url('admin_setting', setting_id='global'),method='put')}
81 81 <div class="form">
82 82 <!-- fields -->
83 83
84 84 <div class="fields">
85 85
86 86 <div class="field">
87 87 <div class="label">
88 88 <label for="rhodecode_title">${_('Site branding')}:</label>
89 89 </div>
90 90 <div class="input">
91 91 ${h.text('rhodecode_title',size=30)}
92 92 </div>
93 93 </div>
94 94
95 95 <div class="field">
96 96 <div class="label">
97 97 <label for="rhodecode_realm">${_('HTTP authentication realm')}:</label>
98 98 </div>
99 99 <div class="input">
100 100 ${h.text('rhodecode_realm',size=30)}
101 101 </div>
102 102 </div>
103 103
104 104 <div class="field">
105 105 <div class="label">
106 106 <label for="rhodecode_ga_code">${_('Google Analytics code')}:</label>
107 107 </div>
108 108 <div class="input">
109 109 ${h.text('rhodecode_ga_code',size=30)}
110 110 </div>
111 111 </div>
112 112
113 113 <div class="buttons">
114 114 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
115 115 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
116 116 </div>
117 117 </div>
118 118 </div>
119 119 ${h.end_form()}
120 120
121 121 <h3>${_('Visualisation settings')}</h3>
122 122 ${h.form(url('admin_setting', setting_id='visual'),method='put')}
123 123 <div class="form">
124 124 <!-- fields -->
125 125
126 126 <div class="fields">
127 127 <div class="field">
128 128 <div class="label label-checkbox">
129 129 <label>${_('General')}:</label>
130 130 </div>
131 131 <div class="checkboxes">
132 132 <div class="checkbox">
133 133 ${h.checkbox('rhodecode_repository_fields','True')}
134 134 <label for="rhodecode_repository_fields">${_('Use repository extra fields')}</label>
135 135 </div>
136 136 <span class="help-block">${_('Allows storing additional customized fields per repository.')}</span>
137 137 <div class="checkbox">
138 138 ${h.checkbox('rhodecode_show_version','True')}
139 139 <label for="rhodecode_show_version">${_('Show RhodeCode version')}</label>
140 140 </div>
141 141 <span class="help-block">${_('Shows or hides displayed version of RhodeCode in the footer')}</span>
142 142 </div>
143 143 </div>
144 144 <div class="field">
145 145 <div class="label">
146 146 <label for="rhodecode_realm">${_('Dashboard items')}:</label>
147 147 </div>
148 148 <div class="input">
149 149 ${h.text('rhodecode_dashboard_items',size=5)}
150 150 <span class="help-block">${_('Number of items displayed in lightweight dashboard before pagination is shown.')}</span>
151 151 </div>
152 152 </div>
153 153 <div class="field">
154 154 <div class="label label-checkbox">
155 155 <label>${_('Icons')}:</label>
156 156 </div>
157 157 <div class="checkboxes">
158 158 <div class="checkbox">
159 159 ${h.checkbox('rhodecode_show_public_icon','True')}
160 160 <label for="rhodecode_show_public_icon">${_('Show public repo icon on repositories')}</label>
161 161 </div>
162 162 <div class="checkbox">
163 163 ${h.checkbox('rhodecode_show_private_icon','True')}
164 164 <label for="rhodecode_show_private_icon">${_('Show private repo icon on repositories')}</label>
165 165 </div>
166 166 <span class="help-block">${_('Show public/private icons next to repositories names')}</span>
167 167 </div>
168 168 </div>
169 169
170 170 <div class="field">
171 171 <div class="label label-checkbox">
172 172 <label>${_('Meta-Tagging')}:</label>
173 173 </div>
174 174 <div class="checkboxes">
175 175 <div class="checkbox">
176 176 ${h.checkbox('rhodecode_stylify_metatags','True')}
177 177 <label for="rhodecode_stylify_metatags">${_('Stylify recognised metatags:')}</label>
178 178 </div>
179 179 <div style="padding-left: 20px;">
180 180 <ul> <!-- Fix style here -->
181 181 <li>[featured] <span class="metatag" tag="featured">featured</span></li>
182 182 <li>[stale] <span class="metatag" tag="stale">stale</span></li>
183 183 <li>[dead] <span class="metatag" tag="dead">dead</span></li>
184 184 <li>[lang =&gt; lang] <span class="metatag" tag="lang" >lang</span></li>
185 185 <li>[license =&gt; License] <span class="metatag" tag="license"><a href="http://www.opensource.org/licenses/License" >License</a></span></li>
186 186 <li>[requires =&gt; Repo] <span class="metatag" tag="requires" >requires =&gt; <a href="#" >Repo</a></span></li>
187 187 <li>[recommends =&gt; Repo] <span class="metatag" tag="recommends" >recommends =&gt; <a href="#" >Repo</a></span></li>
188 188 <li>[see =&gt; URI] <span class="metatag" tag="see">see =&gt; <a href="#">URI</a> </span></li>
189 189 </ul>
190 190 </div>
191 191 </div>
192 192 </div>
193 193
194 194 <div class="buttons">
195 195 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
196 196 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
197 197 </div>
198 198
199 199 </div>
200 200 </div>
201 201 ${h.end_form()}
202 202
203 203
204 204 <h3>${_('VCS settings')}</h3>
205 205 ${h.form(url('admin_setting', setting_id='vcs'),method='put')}
206 206 <div class="form">
207 207 <!-- fields -->
208 208
209 209 <div class="fields">
210 210
211 211 <div class="field">
212 212 <div class="label label-checkbox">
213 213 <label>${_('Web')}:</label>
214 214 </div>
215 215 <div class="checkboxes">
216 216 <div class="checkbox">
217 217 ${h.checkbox('web_push_ssl', 'True')}
218 218 <label for="web_push_ssl">${_('Require SSL for vcs operations')}</label>
219 219 </div>
220 220 <span class="help-block">${_('RhodeCode will require SSL for pushing or pulling. If SSL is missing it will return HTTP Error 406: Not Acceptable')}</span>
221 221 </div>
222 222 </div>
223 223
224 224 <div class="field">
225 225 <div class="label label-checkbox">
226 226 <label>${_('Hooks')}:</label>
227 227 </div>
228 228 <div class="checkboxes">
229 229 <div class="checkbox">
230 230 ${h.checkbox('hooks_changegroup_update','True')}
231 231 <label for="hooks_changegroup_update">${_('Update repository after push (hg update)')}</label>
232 232 </div>
233 233 <div class="checkbox">
234 234 ${h.checkbox('hooks_changegroup_repo_size','True')}
235 235 <label for="hooks_changegroup_repo_size">${_('Show repository size after push')}</label>
236 236 </div>
237 237 <div class="checkbox">
238 238 ${h.checkbox('hooks_changegroup_push_logger','True')}
239 239 <label for="hooks_changegroup_push_logger">${_('Log user push commands')}</label>
240 240 </div>
241 241 <div class="checkbox">
242 242 ${h.checkbox('hooks_outgoing_pull_logger','True')}
243 243 <label for="hooks_outgoing_pull_logger">${_('Log user pull commands')}</label>
244 244 </div>
245 245 </div>
246 246 <div class="input" style="margin-top:10px">
247 247 ${h.link_to(_('Advanced setup'),url('admin_edit_setting',setting_id='hooks'))}
248 248 </div>
249 249 </div>
250 250 <div class="field">
251 251 <div class="label label-checkbox">
252 252 <label>${_('Mercurial Extensions')}:</label>
253 253 </div>
254 254 <div class="checkboxes">
255 255 <div class="checkbox">
256 256 ${h.checkbox('extensions_largefiles','True')}
257 257 <label for="extensions_largefiles">${_('Enable largefiles extension')}</label>
258 258 </div>
259 259 <div class="checkbox">
260 260 ${h.checkbox('extensions_hgsubversion','True')}
261 261 <label for="extensions_hgsubversion">${_('Enable hgsubversion extension')}</label>
262 262 </div>
263 263 <span class="help-block">${_('Requires hgsubversion library installed. Allows cloning from svn remote locations')}</span>
264 264 ##<div class="checkbox">
265 265 ## ${h.checkbox('extensions_hggit','True')}
266 266 ## <label for="extensions_hggit">${_('Enable hg-git extension')}</label>
267 267 ##</div>
268 268 ##<span class="help-block">${_('Requires hg-git library installed. Allows cloning from git remote locations')}</span>
269 269 </div>
270 270 </div>
271 %if c.visual.allow_repo_location_change:
271 272 <div class="field">
272 273 <div class="label">
273 274 <label for="paths_root_path">${_('Repositories location')}:</label>
274 275 </div>
275 276 <div class="input">
276 ${h.text('paths_root_path',size=30,readonly="readonly")}
277 <span id="path_unlock" class="tooltip"
278 title="${h.tooltip(_('This a crucial application setting. If you are really sure you need to change this, you must restart application in order to make this setting take effect. Click this label to unlock.'))}">
277 ${h.text('paths_root_path',size=30,readonly="readonly", class_="disabled")}
278 <span id="path_unlock" class="tooltip" style="cursor: pointer"
279 title="${h.tooltip(_('Click to unlock. You must restart RhodeCode in order to make this setting take effect.'))}">
279 280 ${_('Unlock')}
280 281 </span>
281 282 <span class="help-block">${_('Location where repositories are stored. After changing this value a restart, and rescan is required')}</span>
282 283 </div>
283 284 </div>
284
285 %endif
285 286 <div class="buttons">
286 287 ${h.submit('save',_('Save settings'),class_="ui-btn large")}
287 288 ${h.reset('reset',_('Reset'),class_="ui-btn large")}
288 289 </div>
289 290 </div>
290 291 </div>
291 292 ${h.end_form()}
292 293
293 294 <script type="text/javascript">
294 295 YAHOO.util.Event.onDOMReady(function(){
295 YAHOO.util.Event.addListener('path_unlock','click',function(){
296 YAHOO.util.Dom.get('paths_root_path').removeAttribute('readonly');
296 YUE.on('path_unlock','click',function(){
297 YUD.get('paths_root_path').removeAttribute('readonly');
298 YUD.removeClass('paths_root_path', 'disabled')
297 299 });
298 300 });
299 301 </script>
300 302
301 303 <h3>${_('Test Email')}</h3>
302 304 ${h.form(url('admin_setting', setting_id='email'),method='put')}
303 305 <div class="form">
304 306 <!-- fields -->
305 307
306 308 <div class="fields">
307 309 <div class="field">
308 310 <div class="label">
309 311 <label for="test_email">${_('Email to')}:</label>
310 312 </div>
311 313 <div class="input">
312 314 ${h.text('test_email',size=30)}
313 315 </div>
314 316 </div>
315 317
316 318 <div class="buttons">
317 319 ${h.submit('send',_('Send'),class_="ui-btn large")}
318 320 </div>
319 321 </div>
320 322 </div>
321 323 ${h.end_form()}
322 324
323 325 <h3>${_('System Info and Packages')}</h3>
324 326 <div class="form">
325 327 <div>
326 328 <h5 id="expand_modules" style="cursor: pointer">&darr; ${_('Show')} &darr;</h5>
327 329 </div>
328 330 <div id="expand_modules_table" style="display:none">
329 331 <h5>Python - ${c.py_version}</h5>
330 332 <h5>System - ${c.platform}</h5>
331 333
332 334 <table class="table" style="margin:0px 0px 0px 20px">
333 335 <colgroup>
334 336 <col style="width:220px">
335 337 </colgroup>
336 338 <tbody>
337 339 %for key, value in c.modules:
338 340 <tr>
339 341 <th style="text-align: right;padding-right:5px;">${key}</th>
340 342 <td>${value}</td>
341 343 </tr>
342 344 %endfor
343 345 </tbody>
344 346 </table>
345 347 </div>
346 348 </div>
347 349
348 350 <script type="text/javascript">
349 351 YUE.on('expand_modules','click',function(e){
350 352 YUD.setStyle('expand_modules_table','display','');
351 353 YUD.setStyle('expand_modules','display','none');
352 354 })
353 355 </script>
354 356
355 357 </div>
356 358 </%def>
General Comments 0
You need to be logged in to leave comments. Login now