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