##// END OF EJS Templates
Implemented #647, option to pass list of default encoding used to encode to/decode from unicode
marcink -
r3008:6e76b489 beta
parent child Browse files
Show More
@@ -1,422 +1,424 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 ##nr of threads to spawn
32 ##nr of threads to spawn
33 #threadpool_workers = 5
33 #threadpool_workers = 5
34
34
35 ##max request before thread respawn
35 ##max request before thread respawn
36 #threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37
37
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 #use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 use = egg:waitress#main
43 host = 0.0.0.0
43 host = 0.0.0.0
44 port = 5000
44 port = 5000
45
45
46 [filter:proxy-prefix]
46 [filter:proxy-prefix]
47 # prefix middleware for rc
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
49 prefix = /<your-prefix>
50
50
51 [app:main]
51 [app:main]
52 use = egg:rhodecode
52 use = egg:rhodecode
53 #filter-with = proxy-prefix
53 #filter-with = proxy-prefix
54 full_stack = true
54 full_stack = true
55 static_files = true
55 static_files = true
56 # Optional Languages
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
58 lang = en
58 lang = en
59 cache_dir = %(here)s/data
59 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
60 index_dir = %(here)s/data/index
61 app_instance_uuid = rc-develop
61 app_instance_uuid = rc-develop
62 cut_off_limit = 256000
62 cut_off_limit = 256000
63 force_https = false
63 force_https = false
64 commit_parse_limit = 25
64 commit_parse_limit = 25
65 use_gravatar = true
65 use_gravatar = true
66
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
68 ## the following parts of the URL will be replaced
69 ## {email} user email
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
71 ## {size} size of the image that is expected from the server application
72 ## {scheme} http/https from RhodeCode server
72 ## {scheme} http/https from RhodeCode server
73 ## {netloc} network location from RhodeCode server
73 ## {netloc} network location from RhodeCode server
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
76
76
77 container_auth_enabled = false
77 container_auth_enabled = false
78 proxypass_auth_enabled = false
78 proxypass_auth_enabled = false
79 ## default encoding used to convert from and to unicode
80 ## can be also a comma seperated list of encoding in case of mixed encodings
79 default_encoding = utf8
81 default_encoding = utf8
80
82
81 ## overwrite schema of clone url
83 ## overwrite schema of clone url
82 ## available vars:
84 ## available vars:
83 ## scheme - http/https
85 ## scheme - http/https
84 ## user - current user
86 ## user - current user
85 ## pass - password
87 ## pass - password
86 ## netloc - network location
88 ## netloc - network location
87 ## path - usually repo_name
89 ## path - usually repo_name
88
90
89 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
91 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
90
92
91 ## issue tracking mapping for commits messages
93 ## issue tracking mapping for commits messages
92 ## comment out issue_pat, issue_server, issue_prefix to enable
94 ## comment out issue_pat, issue_server, issue_prefix to enable
93
95
94 ## pattern to get the issues from commit messages
96 ## pattern to get the issues from commit messages
95 ## default one used here is #<numbers> with a regex passive group for `#`
97 ## default one used here is #<numbers> with a regex passive group for `#`
96 ## {id} will be all groups matched from this pattern
98 ## {id} will be all groups matched from this pattern
97
99
98 issue_pat = (?:\s*#)(\d+)
100 issue_pat = (?:\s*#)(\d+)
99
101
100 ## server url to the issue, each {id} will be replaced with match
102 ## server url to the issue, each {id} will be replaced with match
101 ## fetched from the regex and {repo} is replaced with full repository name
103 ## fetched from the regex and {repo} is replaced with full repository name
102 ## including groups {repo_name} is replaced with just name of repo
104 ## including groups {repo_name} is replaced with just name of repo
103
105
104 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
106 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
105
107
106 ## prefix to add to link to indicate it's an url
108 ## prefix to add to link to indicate it's an url
107 ## #314 will be replaced by <issue_prefix><id>
109 ## #314 will be replaced by <issue_prefix><id>
108
110
109 issue_prefix = #
111 issue_prefix = #
110
112
111 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
113 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
112 ## multiple patterns, to other issues server, wiki or others
114 ## multiple patterns, to other issues server, wiki or others
113 ## below an example how to create a wiki pattern
115 ## below an example how to create a wiki pattern
114 # #wiki-some-id -> https://mywiki.com/some-id
116 # #wiki-some-id -> https://mywiki.com/some-id
115
117
116 #issue_pat_wiki = (?:wiki-)(.+)
118 #issue_pat_wiki = (?:wiki-)(.+)
117 #issue_server_link_wiki = https://mywiki.com/{id}
119 #issue_server_link_wiki = https://mywiki.com/{id}
118 #issue_prefix_wiki = WIKI-
120 #issue_prefix_wiki = WIKI-
119
121
120
122
121 ## instance-id prefix
123 ## instance-id prefix
122 ## a prefix key for this instance used for cache invalidation when running
124 ## a prefix key for this instance used for cache invalidation when running
123 ## multiple instances of rhodecode, make sure it's globally unique for
125 ## multiple instances of rhodecode, make sure it's globally unique for
124 ## all running rhodecode instances. Leave empty if you don't use it
126 ## all running rhodecode instances. Leave empty if you don't use it
125 instance_id =
127 instance_id =
126
128
127 ## alternative return HTTP header for failed authentication. Default HTTP
129 ## alternative return HTTP header for failed authentication. Default HTTP
128 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
130 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
129 ## handling that. Set this variable to 403 to return HTTPForbidden
131 ## handling that. Set this variable to 403 to return HTTPForbidden
130 auth_ret_code =
132 auth_ret_code =
131
133
132 ####################################
134 ####################################
133 ### CELERY CONFIG ####
135 ### CELERY CONFIG ####
134 ####################################
136 ####################################
135 use_celery = false
137 use_celery = false
136 broker.host = localhost
138 broker.host = localhost
137 broker.vhost = rabbitmqhost
139 broker.vhost = rabbitmqhost
138 broker.port = 5672
140 broker.port = 5672
139 broker.user = rabbitmq
141 broker.user = rabbitmq
140 broker.password = qweqwe
142 broker.password = qweqwe
141
143
142 celery.imports = rhodecode.lib.celerylib.tasks
144 celery.imports = rhodecode.lib.celerylib.tasks
143
145
144 celery.result.backend = amqp
146 celery.result.backend = amqp
145 celery.result.dburi = amqp://
147 celery.result.dburi = amqp://
146 celery.result.serialier = json
148 celery.result.serialier = json
147
149
148 #celery.send.task.error.emails = true
150 #celery.send.task.error.emails = true
149 #celery.amqp.task.result.expires = 18000
151 #celery.amqp.task.result.expires = 18000
150
152
151 celeryd.concurrency = 2
153 celeryd.concurrency = 2
152 #celeryd.log.file = celeryd.log
154 #celeryd.log.file = celeryd.log
153 celeryd.log.level = debug
155 celeryd.log.level = debug
154 celeryd.max.tasks.per.child = 1
156 celeryd.max.tasks.per.child = 1
155
157
156 #tasks will never be sent to the queue, but executed locally instead.
158 #tasks will never be sent to the queue, but executed locally instead.
157 celery.always.eager = false
159 celery.always.eager = false
158
160
159 ####################################
161 ####################################
160 ### BEAKER CACHE ####
162 ### BEAKER CACHE ####
161 ####################################
163 ####################################
162 beaker.cache.data_dir=%(here)s/data/cache/data
164 beaker.cache.data_dir=%(here)s/data/cache/data
163 beaker.cache.lock_dir=%(here)s/data/cache/lock
165 beaker.cache.lock_dir=%(here)s/data/cache/lock
164
166
165 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
167 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
166
168
167 beaker.cache.super_short_term.type=memory
169 beaker.cache.super_short_term.type=memory
168 beaker.cache.super_short_term.expire=10
170 beaker.cache.super_short_term.expire=10
169 beaker.cache.super_short_term.key_length = 256
171 beaker.cache.super_short_term.key_length = 256
170
172
171 beaker.cache.short_term.type=memory
173 beaker.cache.short_term.type=memory
172 beaker.cache.short_term.expire=60
174 beaker.cache.short_term.expire=60
173 beaker.cache.short_term.key_length = 256
175 beaker.cache.short_term.key_length = 256
174
176
175 beaker.cache.long_term.type=memory
177 beaker.cache.long_term.type=memory
176 beaker.cache.long_term.expire=36000
178 beaker.cache.long_term.expire=36000
177 beaker.cache.long_term.key_length = 256
179 beaker.cache.long_term.key_length = 256
178
180
179 beaker.cache.sql_cache_short.type=memory
181 beaker.cache.sql_cache_short.type=memory
180 beaker.cache.sql_cache_short.expire=10
182 beaker.cache.sql_cache_short.expire=10
181 beaker.cache.sql_cache_short.key_length = 256
183 beaker.cache.sql_cache_short.key_length = 256
182
184
183 beaker.cache.sql_cache_med.type=memory
185 beaker.cache.sql_cache_med.type=memory
184 beaker.cache.sql_cache_med.expire=360
186 beaker.cache.sql_cache_med.expire=360
185 beaker.cache.sql_cache_med.key_length = 256
187 beaker.cache.sql_cache_med.key_length = 256
186
188
187 beaker.cache.sql_cache_long.type=file
189 beaker.cache.sql_cache_long.type=file
188 beaker.cache.sql_cache_long.expire=3600
190 beaker.cache.sql_cache_long.expire=3600
189 beaker.cache.sql_cache_long.key_length = 256
191 beaker.cache.sql_cache_long.key_length = 256
190
192
191 ####################################
193 ####################################
192 ### BEAKER SESSION ####
194 ### BEAKER SESSION ####
193 ####################################
195 ####################################
194 ## Type of storage used for the session, current types are
196 ## Type of storage used for the session, current types are
195 ## dbm, file, memcached, database, and memory.
197 ## dbm, file, memcached, database, and memory.
196 ## The storage uses the Container API
198 ## The storage uses the Container API
197 ## that is also used by the cache system.
199 ## that is also used by the cache system.
198
200
199 ## db session ##
201 ## db session ##
200 #beaker.session.type = ext:database
202 #beaker.session.type = ext:database
201 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
203 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
202 #beaker.session.table_name = db_session
204 #beaker.session.table_name = db_session
203
205
204 ## encrypted cookie client side session, good for many instances ##
206 ## encrypted cookie client side session, good for many instances ##
205 #beaker.session.type = cookie
207 #beaker.session.type = cookie
206
208
207 ## file based cookies (default) ##
209 ## file based cookies (default) ##
208 #beaker.session.type = file
210 #beaker.session.type = file
209
211
210
212
211 beaker.session.key = rhodecode
213 beaker.session.key = rhodecode
212 ## secure cookie requires AES python libraries ##
214 ## secure cookie requires AES python libraries ##
213 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
215 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
214 #beaker.session.validate_key = 9712sds2212c--zxc123
216 #beaker.session.validate_key = 9712sds2212c--zxc123
215 ## sets session as invalid if it haven't been accessed for given amount of time
217 ## sets session as invalid if it haven't been accessed for given amount of time
216 beaker.session.timeout = 2592000
218 beaker.session.timeout = 2592000
217 beaker.session.httponly = true
219 beaker.session.httponly = true
218 #beaker.session.cookie_path = /<your-prefix>
220 #beaker.session.cookie_path = /<your-prefix>
219
221
220 ## uncomment for https secure cookie ##
222 ## uncomment for https secure cookie ##
221 beaker.session.secure = false
223 beaker.session.secure = false
222
224
223 ## auto save the session to not to use .save() ##
225 ## auto save the session to not to use .save() ##
224 beaker.session.auto = False
226 beaker.session.auto = False
225
227
226 ## default cookie expiration time in seconds `true` expire at browser close ##
228 ## default cookie expiration time in seconds `true` expire at browser close ##
227 #beaker.session.cookie_expires = 3600
229 #beaker.session.cookie_expires = 3600
228
230
229
231
230 ############################
232 ############################
231 ## ERROR HANDLING SYSTEMS ##
233 ## ERROR HANDLING SYSTEMS ##
232 ############################
234 ############################
233
235
234 ####################
236 ####################
235 ### [errormator] ###
237 ### [errormator] ###
236 ####################
238 ####################
237
239
238 # Errormator is tailored to work with RhodeCode, see
240 # Errormator is tailored to work with RhodeCode, see
239 # http://errormator.com for details how to obtain an account
241 # http://errormator.com for details how to obtain an account
240 # you must install python package `errormator_client` to make it work
242 # you must install python package `errormator_client` to make it work
241
243
242 # errormator enabled
244 # errormator enabled
243 errormator = true
245 errormator = true
244
246
245 errormator.server_url = https://api.errormator.com
247 errormator.server_url = https://api.errormator.com
246 errormator.api_key = YOUR_API_KEY
248 errormator.api_key = YOUR_API_KEY
247
249
248 # TWEAK AMOUNT OF INFO SENT HERE
250 # TWEAK AMOUNT OF INFO SENT HERE
249
251
250 # enables 404 error logging (default False)
252 # enables 404 error logging (default False)
251 errormator.report_404 = false
253 errormator.report_404 = false
252
254
253 # time in seconds after request is considered being slow (default 1)
255 # time in seconds after request is considered being slow (default 1)
254 errormator.slow_request_time = 1
256 errormator.slow_request_time = 1
255
257
256 # record slow requests in application
258 # record slow requests in application
257 # (needs to be enabled for slow datastore recording and time tracking)
259 # (needs to be enabled for slow datastore recording and time tracking)
258 errormator.slow_requests = true
260 errormator.slow_requests = true
259
261
260 # enable hooking to application loggers
262 # enable hooking to application loggers
261 # errormator.logging = true
263 # errormator.logging = true
262
264
263 # minimum log level for log capture
265 # minimum log level for log capture
264 # errormator.logging.level = WARNING
266 # errormator.logging.level = WARNING
265
267
266 # send logs only from erroneous/slow requests
268 # send logs only from erroneous/slow requests
267 # (saves API quota for intensive logging)
269 # (saves API quota for intensive logging)
268 errormator.logging_on_error = false
270 errormator.logging_on_error = false
269
271
270 # list of additonal keywords that should be grabbed from environ object
272 # list of additonal keywords that should be grabbed from environ object
271 # can be string with comma separated list of words in lowercase
273 # can be string with comma separated list of words in lowercase
272 # (by default client will always send following info:
274 # (by default client will always send following info:
273 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
275 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
274 # start with HTTP* this list be extended with additional keywords here
276 # start with HTTP* this list be extended with additional keywords here
275 errormator.environ_keys_whitelist =
277 errormator.environ_keys_whitelist =
276
278
277
279
278 # list of keywords that should be blanked from request object
280 # list of keywords that should be blanked from request object
279 # can be string with comma separated list of words in lowercase
281 # can be string with comma separated list of words in lowercase
280 # (by default client will always blank keys that contain following words
282 # (by default client will always blank keys that contain following words
281 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
283 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
282 # this list be extended with additional keywords set here
284 # this list be extended with additional keywords set here
283 errormator.request_keys_blacklist =
285 errormator.request_keys_blacklist =
284
286
285
287
286 # list of namespaces that should be ignores when gathering log entries
288 # list of namespaces that should be ignores when gathering log entries
287 # can be string with comma separated list of namespaces
289 # can be string with comma separated list of namespaces
288 # (by default the client ignores own entries: errormator_client.client)
290 # (by default the client ignores own entries: errormator_client.client)
289 errormator.log_namespace_blacklist =
291 errormator.log_namespace_blacklist =
290
292
291
293
292 ################
294 ################
293 ### [sentry] ###
295 ### [sentry] ###
294 ################
296 ################
295
297
296 # sentry is a alternative open source error aggregator
298 # sentry is a alternative open source error aggregator
297 # you must install python packages `sentry` and `raven` to enable
299 # you must install python packages `sentry` and `raven` to enable
298
300
299 sentry.dsn = YOUR_DNS
301 sentry.dsn = YOUR_DNS
300 sentry.servers =
302 sentry.servers =
301 sentry.name =
303 sentry.name =
302 sentry.key =
304 sentry.key =
303 sentry.public_key =
305 sentry.public_key =
304 sentry.secret_key =
306 sentry.secret_key =
305 sentry.project =
307 sentry.project =
306 sentry.site =
308 sentry.site =
307 sentry.include_paths =
309 sentry.include_paths =
308 sentry.exclude_paths =
310 sentry.exclude_paths =
309
311
310
312
311 ################################################################################
313 ################################################################################
312 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
314 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
313 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
315 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
314 ## execute malicious code after an exception is raised. ##
316 ## execute malicious code after an exception is raised. ##
315 ################################################################################
317 ################################################################################
316 #set debug = false
318 #set debug = false
317
319
318 ##################################
320 ##################################
319 ### LOGVIEW CONFIG ###
321 ### LOGVIEW CONFIG ###
320 ##################################
322 ##################################
321 logview.sqlalchemy = #faa
323 logview.sqlalchemy = #faa
322 logview.pylons.templating = #bfb
324 logview.pylons.templating = #bfb
323 logview.pylons.util = #eee
325 logview.pylons.util = #eee
324
326
325 #########################################################
327 #########################################################
326 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
328 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
327 #########################################################
329 #########################################################
328 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
330 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
329 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
331 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
330 sqlalchemy.db1.echo = false
332 sqlalchemy.db1.echo = false
331 sqlalchemy.db1.pool_recycle = 3600
333 sqlalchemy.db1.pool_recycle = 3600
332 sqlalchemy.db1.convert_unicode = true
334 sqlalchemy.db1.convert_unicode = true
333
335
334 ################################
336 ################################
335 ### LOGGING CONFIGURATION ####
337 ### LOGGING CONFIGURATION ####
336 ################################
338 ################################
337 [loggers]
339 [loggers]
338 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
340 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
339
341
340 [handlers]
342 [handlers]
341 keys = console, console_sql
343 keys = console, console_sql
342
344
343 [formatters]
345 [formatters]
344 keys = generic, color_formatter, color_formatter_sql
346 keys = generic, color_formatter, color_formatter_sql
345
347
346 #############
348 #############
347 ## LOGGERS ##
349 ## LOGGERS ##
348 #############
350 #############
349 [logger_root]
351 [logger_root]
350 level = NOTSET
352 level = NOTSET
351 handlers = console
353 handlers = console
352
354
353 [logger_routes]
355 [logger_routes]
354 level = DEBUG
356 level = DEBUG
355 handlers =
357 handlers =
356 qualname = routes.middleware
358 qualname = routes.middleware
357 # "level = DEBUG" logs the route matched and routing variables.
359 # "level = DEBUG" logs the route matched and routing variables.
358 propagate = 1
360 propagate = 1
359
361
360 [logger_beaker]
362 [logger_beaker]
361 level = DEBUG
363 level = DEBUG
362 handlers =
364 handlers =
363 qualname = beaker.container
365 qualname = beaker.container
364 propagate = 1
366 propagate = 1
365
367
366 [logger_templates]
368 [logger_templates]
367 level = INFO
369 level = INFO
368 handlers =
370 handlers =
369 qualname = pylons.templating
371 qualname = pylons.templating
370 propagate = 1
372 propagate = 1
371
373
372 [logger_rhodecode]
374 [logger_rhodecode]
373 level = DEBUG
375 level = DEBUG
374 handlers =
376 handlers =
375 qualname = rhodecode
377 qualname = rhodecode
376 propagate = 1
378 propagate = 1
377
379
378 [logger_sqlalchemy]
380 [logger_sqlalchemy]
379 level = INFO
381 level = INFO
380 handlers = console_sql
382 handlers = console_sql
381 qualname = sqlalchemy.engine
383 qualname = sqlalchemy.engine
382 propagate = 0
384 propagate = 0
383
385
384 [logger_whoosh_indexer]
386 [logger_whoosh_indexer]
385 level = DEBUG
387 level = DEBUG
386 handlers =
388 handlers =
387 qualname = whoosh_indexer
389 qualname = whoosh_indexer
388 propagate = 1
390 propagate = 1
389
391
390 ##############
392 ##############
391 ## HANDLERS ##
393 ## HANDLERS ##
392 ##############
394 ##############
393
395
394 [handler_console]
396 [handler_console]
395 class = StreamHandler
397 class = StreamHandler
396 args = (sys.stderr,)
398 args = (sys.stderr,)
397 level = DEBUG
399 level = DEBUG
398 formatter = color_formatter
400 formatter = color_formatter
399
401
400 [handler_console_sql]
402 [handler_console_sql]
401 class = StreamHandler
403 class = StreamHandler
402 args = (sys.stderr,)
404 args = (sys.stderr,)
403 level = DEBUG
405 level = DEBUG
404 formatter = color_formatter_sql
406 formatter = color_formatter_sql
405
407
406 ################
408 ################
407 ## FORMATTERS ##
409 ## FORMATTERS ##
408 ################
410 ################
409
411
410 [formatter_generic]
412 [formatter_generic]
411 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
413 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
412 datefmt = %Y-%m-%d %H:%M:%S
414 datefmt = %Y-%m-%d %H:%M:%S
413
415
414 [formatter_color_formatter]
416 [formatter_color_formatter]
415 class=rhodecode.lib.colored_formatter.ColorFormatter
417 class=rhodecode.lib.colored_formatter.ColorFormatter
416 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
418 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
417 datefmt = %Y-%m-%d %H:%M:%S
419 datefmt = %Y-%m-%d %H:%M:%S
418
420
419 [formatter_color_formatter_sql]
421 [formatter_color_formatter_sql]
420 class=rhodecode.lib.colored_formatter.ColorFormatterSql
422 class=rhodecode.lib.colored_formatter.ColorFormatterSql
421 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
423 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
422 datefmt = %Y-%m-%d %H:%M:%S
424 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,422 +1,424 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 ##nr of threads to spawn
32 ##nr of threads to spawn
33 #threadpool_workers = 5
33 #threadpool_workers = 5
34
34
35 ##max request before thread respawn
35 ##max request before thread respawn
36 #threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37
37
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 #use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 use = egg:waitress#main
43 host = 127.0.0.1
43 host = 127.0.0.1
44 port = 8001
44 port = 8001
45
45
46 [filter:proxy-prefix]
46 [filter:proxy-prefix]
47 # prefix middleware for rc
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
49 prefix = /<your-prefix>
50
50
51 [app:main]
51 [app:main]
52 use = egg:rhodecode
52 use = egg:rhodecode
53 #filter-with = proxy-prefix
53 #filter-with = proxy-prefix
54 full_stack = true
54 full_stack = true
55 static_files = true
55 static_files = true
56 # Optional Languages
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
58 lang = en
58 lang = en
59 cache_dir = %(here)s/data
59 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
60 index_dir = %(here)s/data/index
61 app_instance_uuid = rc-production
61 app_instance_uuid = rc-production
62 cut_off_limit = 256000
62 cut_off_limit = 256000
63 force_https = false
63 force_https = false
64 commit_parse_limit = 50
64 commit_parse_limit = 50
65 use_gravatar = true
65 use_gravatar = true
66
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
68 ## the following parts of the URL will be replaced
69 ## {email} user email
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
71 ## {size} size of the image that is expected from the server application
72 ## {scheme} http/https from RhodeCode server
72 ## {scheme} http/https from RhodeCode server
73 ## {netloc} network location from RhodeCode server
73 ## {netloc} network location from RhodeCode server
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
76
76
77 container_auth_enabled = false
77 container_auth_enabled = false
78 proxypass_auth_enabled = false
78 proxypass_auth_enabled = false
79 ## default encoding used to convert from and to unicode
80 ## can be also a comma seperated list of encoding in case of mixed encodings
79 default_encoding = utf8
81 default_encoding = utf8
80
82
81 ## overwrite schema of clone url
83 ## overwrite schema of clone url
82 ## available vars:
84 ## available vars:
83 ## scheme - http/https
85 ## scheme - http/https
84 ## user - current user
86 ## user - current user
85 ## pass - password
87 ## pass - password
86 ## netloc - network location
88 ## netloc - network location
87 ## path - usually repo_name
89 ## path - usually repo_name
88
90
89 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
91 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
90
92
91 ## issue tracking mapping for commits messages
93 ## issue tracking mapping for commits messages
92 ## comment out issue_pat, issue_server, issue_prefix to enable
94 ## comment out issue_pat, issue_server, issue_prefix to enable
93
95
94 ## pattern to get the issues from commit messages
96 ## pattern to get the issues from commit messages
95 ## default one used here is #<numbers> with a regex passive group for `#`
97 ## default one used here is #<numbers> with a regex passive group for `#`
96 ## {id} will be all groups matched from this pattern
98 ## {id} will be all groups matched from this pattern
97
99
98 issue_pat = (?:\s*#)(\d+)
100 issue_pat = (?:\s*#)(\d+)
99
101
100 ## server url to the issue, each {id} will be replaced with match
102 ## server url to the issue, each {id} will be replaced with match
101 ## fetched from the regex and {repo} is replaced with full repository name
103 ## fetched from the regex and {repo} is replaced with full repository name
102 ## including groups {repo_name} is replaced with just name of repo
104 ## including groups {repo_name} is replaced with just name of repo
103
105
104 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
106 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
105
107
106 ## prefix to add to link to indicate it's an url
108 ## prefix to add to link to indicate it's an url
107 ## #314 will be replaced by <issue_prefix><id>
109 ## #314 will be replaced by <issue_prefix><id>
108
110
109 issue_prefix = #
111 issue_prefix = #
110
112
111 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
113 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
112 ## multiple patterns, to other issues server, wiki or others
114 ## multiple patterns, to other issues server, wiki or others
113 ## below an example how to create a wiki pattern
115 ## below an example how to create a wiki pattern
114 # #wiki-some-id -> https://mywiki.com/some-id
116 # #wiki-some-id -> https://mywiki.com/some-id
115
117
116 #issue_pat_wiki = (?:wiki-)(.+)
118 #issue_pat_wiki = (?:wiki-)(.+)
117 #issue_server_link_wiki = https://mywiki.com/{id}
119 #issue_server_link_wiki = https://mywiki.com/{id}
118 #issue_prefix_wiki = WIKI-
120 #issue_prefix_wiki = WIKI-
119
121
120
122
121 ## instance-id prefix
123 ## instance-id prefix
122 ## a prefix key for this instance used for cache invalidation when running
124 ## a prefix key for this instance used for cache invalidation when running
123 ## multiple instances of rhodecode, make sure it's globally unique for
125 ## multiple instances of rhodecode, make sure it's globally unique for
124 ## all running rhodecode instances. Leave empty if you don't use it
126 ## all running rhodecode instances. Leave empty if you don't use it
125 instance_id =
127 instance_id =
126
128
127 ## alternative return HTTP header for failed authentication. Default HTTP
129 ## alternative return HTTP header for failed authentication. Default HTTP
128 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
130 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
129 ## handling that. Set this variable to 403 to return HTTPForbidden
131 ## handling that. Set this variable to 403 to return HTTPForbidden
130 auth_ret_code =
132 auth_ret_code =
131
133
132 ####################################
134 ####################################
133 ### CELERY CONFIG ####
135 ### CELERY CONFIG ####
134 ####################################
136 ####################################
135 use_celery = false
137 use_celery = false
136 broker.host = localhost
138 broker.host = localhost
137 broker.vhost = rabbitmqhost
139 broker.vhost = rabbitmqhost
138 broker.port = 5672
140 broker.port = 5672
139 broker.user = rabbitmq
141 broker.user = rabbitmq
140 broker.password = qweqwe
142 broker.password = qweqwe
141
143
142 celery.imports = rhodecode.lib.celerylib.tasks
144 celery.imports = rhodecode.lib.celerylib.tasks
143
145
144 celery.result.backend = amqp
146 celery.result.backend = amqp
145 celery.result.dburi = amqp://
147 celery.result.dburi = amqp://
146 celery.result.serialier = json
148 celery.result.serialier = json
147
149
148 #celery.send.task.error.emails = true
150 #celery.send.task.error.emails = true
149 #celery.amqp.task.result.expires = 18000
151 #celery.amqp.task.result.expires = 18000
150
152
151 celeryd.concurrency = 2
153 celeryd.concurrency = 2
152 #celeryd.log.file = celeryd.log
154 #celeryd.log.file = celeryd.log
153 celeryd.log.level = debug
155 celeryd.log.level = debug
154 celeryd.max.tasks.per.child = 1
156 celeryd.max.tasks.per.child = 1
155
157
156 #tasks will never be sent to the queue, but executed locally instead.
158 #tasks will never be sent to the queue, but executed locally instead.
157 celery.always.eager = false
159 celery.always.eager = false
158
160
159 ####################################
161 ####################################
160 ### BEAKER CACHE ####
162 ### BEAKER CACHE ####
161 ####################################
163 ####################################
162 beaker.cache.data_dir=%(here)s/data/cache/data
164 beaker.cache.data_dir=%(here)s/data/cache/data
163 beaker.cache.lock_dir=%(here)s/data/cache/lock
165 beaker.cache.lock_dir=%(here)s/data/cache/lock
164
166
165 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
167 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
166
168
167 beaker.cache.super_short_term.type=memory
169 beaker.cache.super_short_term.type=memory
168 beaker.cache.super_short_term.expire=10
170 beaker.cache.super_short_term.expire=10
169 beaker.cache.super_short_term.key_length = 256
171 beaker.cache.super_short_term.key_length = 256
170
172
171 beaker.cache.short_term.type=memory
173 beaker.cache.short_term.type=memory
172 beaker.cache.short_term.expire=60
174 beaker.cache.short_term.expire=60
173 beaker.cache.short_term.key_length = 256
175 beaker.cache.short_term.key_length = 256
174
176
175 beaker.cache.long_term.type=memory
177 beaker.cache.long_term.type=memory
176 beaker.cache.long_term.expire=36000
178 beaker.cache.long_term.expire=36000
177 beaker.cache.long_term.key_length = 256
179 beaker.cache.long_term.key_length = 256
178
180
179 beaker.cache.sql_cache_short.type=memory
181 beaker.cache.sql_cache_short.type=memory
180 beaker.cache.sql_cache_short.expire=10
182 beaker.cache.sql_cache_short.expire=10
181 beaker.cache.sql_cache_short.key_length = 256
183 beaker.cache.sql_cache_short.key_length = 256
182
184
183 beaker.cache.sql_cache_med.type=memory
185 beaker.cache.sql_cache_med.type=memory
184 beaker.cache.sql_cache_med.expire=360
186 beaker.cache.sql_cache_med.expire=360
185 beaker.cache.sql_cache_med.key_length = 256
187 beaker.cache.sql_cache_med.key_length = 256
186
188
187 beaker.cache.sql_cache_long.type=file
189 beaker.cache.sql_cache_long.type=file
188 beaker.cache.sql_cache_long.expire=3600
190 beaker.cache.sql_cache_long.expire=3600
189 beaker.cache.sql_cache_long.key_length = 256
191 beaker.cache.sql_cache_long.key_length = 256
190
192
191 ####################################
193 ####################################
192 ### BEAKER SESSION ####
194 ### BEAKER SESSION ####
193 ####################################
195 ####################################
194 ## Type of storage used for the session, current types are
196 ## Type of storage used for the session, current types are
195 ## dbm, file, memcached, database, and memory.
197 ## dbm, file, memcached, database, and memory.
196 ## The storage uses the Container API
198 ## The storage uses the Container API
197 ## that is also used by the cache system.
199 ## that is also used by the cache system.
198
200
199 ## db session ##
201 ## db session ##
200 #beaker.session.type = ext:database
202 #beaker.session.type = ext:database
201 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
203 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
202 #beaker.session.table_name = db_session
204 #beaker.session.table_name = db_session
203
205
204 ## encrypted cookie client side session, good for many instances ##
206 ## encrypted cookie client side session, good for many instances ##
205 #beaker.session.type = cookie
207 #beaker.session.type = cookie
206
208
207 ## file based cookies (default) ##
209 ## file based cookies (default) ##
208 #beaker.session.type = file
210 #beaker.session.type = file
209
211
210
212
211 beaker.session.key = rhodecode
213 beaker.session.key = rhodecode
212 ## secure cookie requires AES python libraries ##
214 ## secure cookie requires AES python libraries ##
213 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
215 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
214 #beaker.session.validate_key = 9712sds2212c--zxc123
216 #beaker.session.validate_key = 9712sds2212c--zxc123
215 ## sets session as invalid if it haven't been accessed for given amount of time
217 ## sets session as invalid if it haven't been accessed for given amount of time
216 beaker.session.timeout = 2592000
218 beaker.session.timeout = 2592000
217 beaker.session.httponly = true
219 beaker.session.httponly = true
218 #beaker.session.cookie_path = /<your-prefix>
220 #beaker.session.cookie_path = /<your-prefix>
219
221
220 ## uncomment for https secure cookie ##
222 ## uncomment for https secure cookie ##
221 beaker.session.secure = false
223 beaker.session.secure = false
222
224
223 ## auto save the session to not to use .save() ##
225 ## auto save the session to not to use .save() ##
224 beaker.session.auto = False
226 beaker.session.auto = False
225
227
226 ## default cookie expiration time in seconds `true` expire at browser close ##
228 ## default cookie expiration time in seconds `true` expire at browser close ##
227 #beaker.session.cookie_expires = 3600
229 #beaker.session.cookie_expires = 3600
228
230
229
231
230 ############################
232 ############################
231 ## ERROR HANDLING SYSTEMS ##
233 ## ERROR HANDLING SYSTEMS ##
232 ############################
234 ############################
233
235
234 ####################
236 ####################
235 ### [errormator] ###
237 ### [errormator] ###
236 ####################
238 ####################
237
239
238 # Errormator is tailored to work with RhodeCode, see
240 # Errormator is tailored to work with RhodeCode, see
239 # http://errormator.com for details how to obtain an account
241 # http://errormator.com for details how to obtain an account
240 # you must install python package `errormator_client` to make it work
242 # you must install python package `errormator_client` to make it work
241
243
242 # errormator enabled
244 # errormator enabled
243 errormator = true
245 errormator = true
244
246
245 errormator.server_url = https://api.errormator.com
247 errormator.server_url = https://api.errormator.com
246 errormator.api_key = YOUR_API_KEY
248 errormator.api_key = YOUR_API_KEY
247
249
248 # TWEAK AMOUNT OF INFO SENT HERE
250 # TWEAK AMOUNT OF INFO SENT HERE
249
251
250 # enables 404 error logging (default False)
252 # enables 404 error logging (default False)
251 errormator.report_404 = false
253 errormator.report_404 = false
252
254
253 # time in seconds after request is considered being slow (default 1)
255 # time in seconds after request is considered being slow (default 1)
254 errormator.slow_request_time = 1
256 errormator.slow_request_time = 1
255
257
256 # record slow requests in application
258 # record slow requests in application
257 # (needs to be enabled for slow datastore recording and time tracking)
259 # (needs to be enabled for slow datastore recording and time tracking)
258 errormator.slow_requests = true
260 errormator.slow_requests = true
259
261
260 # enable hooking to application loggers
262 # enable hooking to application loggers
261 # errormator.logging = true
263 # errormator.logging = true
262
264
263 # minimum log level for log capture
265 # minimum log level for log capture
264 # errormator.logging.level = WARNING
266 # errormator.logging.level = WARNING
265
267
266 # send logs only from erroneous/slow requests
268 # send logs only from erroneous/slow requests
267 # (saves API quota for intensive logging)
269 # (saves API quota for intensive logging)
268 errormator.logging_on_error = false
270 errormator.logging_on_error = false
269
271
270 # list of additonal keywords that should be grabbed from environ object
272 # list of additonal keywords that should be grabbed from environ object
271 # can be string with comma separated list of words in lowercase
273 # can be string with comma separated list of words in lowercase
272 # (by default client will always send following info:
274 # (by default client will always send following info:
273 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
275 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
274 # start with HTTP* this list be extended with additional keywords here
276 # start with HTTP* this list be extended with additional keywords here
275 errormator.environ_keys_whitelist =
277 errormator.environ_keys_whitelist =
276
278
277
279
278 # list of keywords that should be blanked from request object
280 # list of keywords that should be blanked from request object
279 # can be string with comma separated list of words in lowercase
281 # can be string with comma separated list of words in lowercase
280 # (by default client will always blank keys that contain following words
282 # (by default client will always blank keys that contain following words
281 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
283 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
282 # this list be extended with additional keywords set here
284 # this list be extended with additional keywords set here
283 errormator.request_keys_blacklist =
285 errormator.request_keys_blacklist =
284
286
285
287
286 # list of namespaces that should be ignores when gathering log entries
288 # list of namespaces that should be ignores when gathering log entries
287 # can be string with comma separated list of namespaces
289 # can be string with comma separated list of namespaces
288 # (by default the client ignores own entries: errormator_client.client)
290 # (by default the client ignores own entries: errormator_client.client)
289 errormator.log_namespace_blacklist =
291 errormator.log_namespace_blacklist =
290
292
291
293
292 ################
294 ################
293 ### [sentry] ###
295 ### [sentry] ###
294 ################
296 ################
295
297
296 # sentry is a alternative open source error aggregator
298 # sentry is a alternative open source error aggregator
297 # you must install python packages `sentry` and `raven` to enable
299 # you must install python packages `sentry` and `raven` to enable
298
300
299 sentry.dsn = YOUR_DNS
301 sentry.dsn = YOUR_DNS
300 sentry.servers =
302 sentry.servers =
301 sentry.name =
303 sentry.name =
302 sentry.key =
304 sentry.key =
303 sentry.public_key =
305 sentry.public_key =
304 sentry.secret_key =
306 sentry.secret_key =
305 sentry.project =
307 sentry.project =
306 sentry.site =
308 sentry.site =
307 sentry.include_paths =
309 sentry.include_paths =
308 sentry.exclude_paths =
310 sentry.exclude_paths =
309
311
310
312
311 ################################################################################
313 ################################################################################
312 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
314 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
313 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
315 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
314 ## execute malicious code after an exception is raised. ##
316 ## execute malicious code after an exception is raised. ##
315 ################################################################################
317 ################################################################################
316 set debug = false
318 set debug = false
317
319
318 ##################################
320 ##################################
319 ### LOGVIEW CONFIG ###
321 ### LOGVIEW CONFIG ###
320 ##################################
322 ##################################
321 logview.sqlalchemy = #faa
323 logview.sqlalchemy = #faa
322 logview.pylons.templating = #bfb
324 logview.pylons.templating = #bfb
323 logview.pylons.util = #eee
325 logview.pylons.util = #eee
324
326
325 #########################################################
327 #########################################################
326 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
328 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
327 #########################################################
329 #########################################################
328 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
330 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
329 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
331 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
330 sqlalchemy.db1.echo = false
332 sqlalchemy.db1.echo = false
331 sqlalchemy.db1.pool_recycle = 3600
333 sqlalchemy.db1.pool_recycle = 3600
332 sqlalchemy.db1.convert_unicode = true
334 sqlalchemy.db1.convert_unicode = true
333
335
334 ################################
336 ################################
335 ### LOGGING CONFIGURATION ####
337 ### LOGGING CONFIGURATION ####
336 ################################
338 ################################
337 [loggers]
339 [loggers]
338 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
340 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
339
341
340 [handlers]
342 [handlers]
341 keys = console, console_sql
343 keys = console, console_sql
342
344
343 [formatters]
345 [formatters]
344 keys = generic, color_formatter, color_formatter_sql
346 keys = generic, color_formatter, color_formatter_sql
345
347
346 #############
348 #############
347 ## LOGGERS ##
349 ## LOGGERS ##
348 #############
350 #############
349 [logger_root]
351 [logger_root]
350 level = NOTSET
352 level = NOTSET
351 handlers = console
353 handlers = console
352
354
353 [logger_routes]
355 [logger_routes]
354 level = DEBUG
356 level = DEBUG
355 handlers =
357 handlers =
356 qualname = routes.middleware
358 qualname = routes.middleware
357 # "level = DEBUG" logs the route matched and routing variables.
359 # "level = DEBUG" logs the route matched and routing variables.
358 propagate = 1
360 propagate = 1
359
361
360 [logger_beaker]
362 [logger_beaker]
361 level = DEBUG
363 level = DEBUG
362 handlers =
364 handlers =
363 qualname = beaker.container
365 qualname = beaker.container
364 propagate = 1
366 propagate = 1
365
367
366 [logger_templates]
368 [logger_templates]
367 level = INFO
369 level = INFO
368 handlers =
370 handlers =
369 qualname = pylons.templating
371 qualname = pylons.templating
370 propagate = 1
372 propagate = 1
371
373
372 [logger_rhodecode]
374 [logger_rhodecode]
373 level = DEBUG
375 level = DEBUG
374 handlers =
376 handlers =
375 qualname = rhodecode
377 qualname = rhodecode
376 propagate = 1
378 propagate = 1
377
379
378 [logger_sqlalchemy]
380 [logger_sqlalchemy]
379 level = INFO
381 level = INFO
380 handlers = console_sql
382 handlers = console_sql
381 qualname = sqlalchemy.engine
383 qualname = sqlalchemy.engine
382 propagate = 0
384 propagate = 0
383
385
384 [logger_whoosh_indexer]
386 [logger_whoosh_indexer]
385 level = DEBUG
387 level = DEBUG
386 handlers =
388 handlers =
387 qualname = whoosh_indexer
389 qualname = whoosh_indexer
388 propagate = 1
390 propagate = 1
389
391
390 ##############
392 ##############
391 ## HANDLERS ##
393 ## HANDLERS ##
392 ##############
394 ##############
393
395
394 [handler_console]
396 [handler_console]
395 class = StreamHandler
397 class = StreamHandler
396 args = (sys.stderr,)
398 args = (sys.stderr,)
397 level = INFO
399 level = INFO
398 formatter = generic
400 formatter = generic
399
401
400 [handler_console_sql]
402 [handler_console_sql]
401 class = StreamHandler
403 class = StreamHandler
402 args = (sys.stderr,)
404 args = (sys.stderr,)
403 level = WARN
405 level = WARN
404 formatter = generic
406 formatter = generic
405
407
406 ################
408 ################
407 ## FORMATTERS ##
409 ## FORMATTERS ##
408 ################
410 ################
409
411
410 [formatter_generic]
412 [formatter_generic]
411 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
413 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
412 datefmt = %Y-%m-%d %H:%M:%S
414 datefmt = %Y-%m-%d %H:%M:%S
413
415
414 [formatter_color_formatter]
416 [formatter_color_formatter]
415 class=rhodecode.lib.colored_formatter.ColorFormatter
417 class=rhodecode.lib.colored_formatter.ColorFormatter
416 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
418 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
417 datefmt = %Y-%m-%d %H:%M:%S
419 datefmt = %Y-%m-%d %H:%M:%S
418
420
419 [formatter_color_formatter_sql]
421 [formatter_color_formatter_sql]
420 class=rhodecode.lib.colored_formatter.ColorFormatterSql
422 class=rhodecode.lib.colored_formatter.ColorFormatterSql
421 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
423 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
422 datefmt = %Y-%m-%d %H:%M:%S
424 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,432 +1,434 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 ##nr of threads to spawn
32 ##nr of threads to spawn
33 #threadpool_workers = 5
33 #threadpool_workers = 5
34
34
35 ##max request before thread respawn
35 ##max request before thread respawn
36 #threadpool_max_requests = 10
36 #threadpool_max_requests = 10
37
37
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 #use = egg:Paste#http
41 #use = egg:Paste#http
42 use = egg:waitress#main
42 use = egg:waitress#main
43 host = 127.0.0.1
43 host = 127.0.0.1
44 port = 5000
44 port = 5000
45
45
46 [filter:proxy-prefix]
46 [filter:proxy-prefix]
47 # prefix middleware for rc
47 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
48 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
49 prefix = /<your-prefix>
50
50
51 [app:main]
51 [app:main]
52 use = egg:rhodecode
52 use = egg:rhodecode
53 #filter-with = proxy-prefix
53 #filter-with = proxy-prefix
54 full_stack = true
54 full_stack = true
55 static_files = true
55 static_files = true
56 # Optional Languages
56 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
58 lang = en
58 lang = en
59 cache_dir = %(here)s/data
59 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
60 index_dir = %(here)s/data/index
61 app_instance_uuid = ${app_instance_uuid}
61 app_instance_uuid = ${app_instance_uuid}
62 cut_off_limit = 256000
62 cut_off_limit = 256000
63 force_https = false
63 force_https = false
64 commit_parse_limit = 50
64 commit_parse_limit = 50
65 use_gravatar = true
65 use_gravatar = true
66
66
67 ## alternative_gravatar_url allows you to use your own avatar server application
67 ## alternative_gravatar_url allows you to use your own avatar server application
68 ## the following parts of the URL will be replaced
68 ## the following parts of the URL will be replaced
69 ## {email} user email
69 ## {email} user email
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
70 ## {md5email} md5 hash of the user email (like at gravatar.com)
71 ## {size} size of the image that is expected from the server application
71 ## {size} size of the image that is expected from the server application
72 ## {scheme} http/https from RhodeCode server
72 ## {scheme} http/https from RhodeCode server
73 ## {netloc} network location from RhodeCode server
73 ## {netloc} network location from RhodeCode server
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
74 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
75 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
76
76
77 container_auth_enabled = false
77 container_auth_enabled = false
78 proxypass_auth_enabled = false
78 proxypass_auth_enabled = false
79 ## default encoding used to convert from and to unicode
80 ## can be also a comma seperated list of encoding in case of mixed encodings
79 default_encoding = utf8
81 default_encoding = utf8
80
82
81 ## overwrite schema of clone url
83 ## overwrite schema of clone url
82 ## available vars:
84 ## available vars:
83 ## scheme - http/https
85 ## scheme - http/https
84 ## user - current user
86 ## user - current user
85 ## pass - password
87 ## pass - password
86 ## netloc - network location
88 ## netloc - network location
87 ## path - usually repo_name
89 ## path - usually repo_name
88
90
89 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
91 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
90
92
91 ## issue tracking mapping for commits messages
93 ## issue tracking mapping for commits messages
92 ## comment out issue_pat, issue_server, issue_prefix to enable
94 ## comment out issue_pat, issue_server, issue_prefix to enable
93
95
94 ## pattern to get the issues from commit messages
96 ## pattern to get the issues from commit messages
95 ## default one used here is #<numbers> with a regex passive group for `#`
97 ## default one used here is #<numbers> with a regex passive group for `#`
96 ## {id} will be all groups matched from this pattern
98 ## {id} will be all groups matched from this pattern
97
99
98 issue_pat = (?:\s*#)(\d+)
100 issue_pat = (?:\s*#)(\d+)
99
101
100 ## server url to the issue, each {id} will be replaced with match
102 ## server url to the issue, each {id} will be replaced with match
101 ## fetched from the regex and {repo} is replaced with full repository name
103 ## fetched from the regex and {repo} is replaced with full repository name
102 ## including groups {repo_name} is replaced with just name of repo
104 ## including groups {repo_name} is replaced with just name of repo
103
105
104 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
106 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
105
107
106 ## prefix to add to link to indicate it's an url
108 ## prefix to add to link to indicate it's an url
107 ## #314 will be replaced by <issue_prefix><id>
109 ## #314 will be replaced by <issue_prefix><id>
108
110
109 issue_prefix = #
111 issue_prefix = #
110
112
111 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
113 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
112 ## multiple patterns, to other issues server, wiki or others
114 ## multiple patterns, to other issues server, wiki or others
113 ## below an example how to create a wiki pattern
115 ## below an example how to create a wiki pattern
114 # #wiki-some-id -> https://mywiki.com/some-id
116 # #wiki-some-id -> https://mywiki.com/some-id
115
117
116 #issue_pat_wiki = (?:wiki-)(.+)
118 #issue_pat_wiki = (?:wiki-)(.+)
117 #issue_server_link_wiki = https://mywiki.com/{id}
119 #issue_server_link_wiki = https://mywiki.com/{id}
118 #issue_prefix_wiki = WIKI-
120 #issue_prefix_wiki = WIKI-
119
121
120
122
121 ## instance-id prefix
123 ## instance-id prefix
122 ## a prefix key for this instance used for cache invalidation when running
124 ## a prefix key for this instance used for cache invalidation when running
123 ## multiple instances of rhodecode, make sure it's globally unique for
125 ## multiple instances of rhodecode, make sure it's globally unique for
124 ## all running rhodecode instances. Leave empty if you don't use it
126 ## all running rhodecode instances. Leave empty if you don't use it
125 instance_id =
127 instance_id =
126
128
127 ## alternative return HTTP header for failed authentication. Default HTTP
129 ## alternative return HTTP header for failed authentication. Default HTTP
128 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
130 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
129 ## handling that. Set this variable to 403 to return HTTPForbidden
131 ## handling that. Set this variable to 403 to return HTTPForbidden
130 auth_ret_code =
132 auth_ret_code =
131
133
132 ####################################
134 ####################################
133 ### CELERY CONFIG ####
135 ### CELERY CONFIG ####
134 ####################################
136 ####################################
135 use_celery = false
137 use_celery = false
136 broker.host = localhost
138 broker.host = localhost
137 broker.vhost = rabbitmqhost
139 broker.vhost = rabbitmqhost
138 broker.port = 5672
140 broker.port = 5672
139 broker.user = rabbitmq
141 broker.user = rabbitmq
140 broker.password = qweqwe
142 broker.password = qweqwe
141
143
142 celery.imports = rhodecode.lib.celerylib.tasks
144 celery.imports = rhodecode.lib.celerylib.tasks
143
145
144 celery.result.backend = amqp
146 celery.result.backend = amqp
145 celery.result.dburi = amqp://
147 celery.result.dburi = amqp://
146 celery.result.serialier = json
148 celery.result.serialier = json
147
149
148 #celery.send.task.error.emails = true
150 #celery.send.task.error.emails = true
149 #celery.amqp.task.result.expires = 18000
151 #celery.amqp.task.result.expires = 18000
150
152
151 celeryd.concurrency = 2
153 celeryd.concurrency = 2
152 #celeryd.log.file = celeryd.log
154 #celeryd.log.file = celeryd.log
153 celeryd.log.level = debug
155 celeryd.log.level = debug
154 celeryd.max.tasks.per.child = 1
156 celeryd.max.tasks.per.child = 1
155
157
156 #tasks will never be sent to the queue, but executed locally instead.
158 #tasks will never be sent to the queue, but executed locally instead.
157 celery.always.eager = false
159 celery.always.eager = false
158
160
159 ####################################
161 ####################################
160 ### BEAKER CACHE ####
162 ### BEAKER CACHE ####
161 ####################################
163 ####################################
162 beaker.cache.data_dir=%(here)s/data/cache/data
164 beaker.cache.data_dir=%(here)s/data/cache/data
163 beaker.cache.lock_dir=%(here)s/data/cache/lock
165 beaker.cache.lock_dir=%(here)s/data/cache/lock
164
166
165 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
167 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
166
168
167 beaker.cache.super_short_term.type=memory
169 beaker.cache.super_short_term.type=memory
168 beaker.cache.super_short_term.expire=10
170 beaker.cache.super_short_term.expire=10
169 beaker.cache.super_short_term.key_length = 256
171 beaker.cache.super_short_term.key_length = 256
170
172
171 beaker.cache.short_term.type=memory
173 beaker.cache.short_term.type=memory
172 beaker.cache.short_term.expire=60
174 beaker.cache.short_term.expire=60
173 beaker.cache.short_term.key_length = 256
175 beaker.cache.short_term.key_length = 256
174
176
175 beaker.cache.long_term.type=memory
177 beaker.cache.long_term.type=memory
176 beaker.cache.long_term.expire=36000
178 beaker.cache.long_term.expire=36000
177 beaker.cache.long_term.key_length = 256
179 beaker.cache.long_term.key_length = 256
178
180
179 beaker.cache.sql_cache_short.type=memory
181 beaker.cache.sql_cache_short.type=memory
180 beaker.cache.sql_cache_short.expire=10
182 beaker.cache.sql_cache_short.expire=10
181 beaker.cache.sql_cache_short.key_length = 256
183 beaker.cache.sql_cache_short.key_length = 256
182
184
183 beaker.cache.sql_cache_med.type=memory
185 beaker.cache.sql_cache_med.type=memory
184 beaker.cache.sql_cache_med.expire=360
186 beaker.cache.sql_cache_med.expire=360
185 beaker.cache.sql_cache_med.key_length = 256
187 beaker.cache.sql_cache_med.key_length = 256
186
188
187 beaker.cache.sql_cache_long.type=file
189 beaker.cache.sql_cache_long.type=file
188 beaker.cache.sql_cache_long.expire=3600
190 beaker.cache.sql_cache_long.expire=3600
189 beaker.cache.sql_cache_long.key_length = 256
191 beaker.cache.sql_cache_long.key_length = 256
190
192
191 ####################################
193 ####################################
192 ### BEAKER SESSION ####
194 ### BEAKER SESSION ####
193 ####################################
195 ####################################
194 ## Type of storage used for the session, current types are
196 ## Type of storage used for the session, current types are
195 ## dbm, file, memcached, database, and memory.
197 ## dbm, file, memcached, database, and memory.
196 ## The storage uses the Container API
198 ## The storage uses the Container API
197 ## that is also used by the cache system.
199 ## that is also used by the cache system.
198
200
199 ## db session ##
201 ## db session ##
200 #beaker.session.type = ext:database
202 #beaker.session.type = ext:database
201 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
203 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
202 #beaker.session.table_name = db_session
204 #beaker.session.table_name = db_session
203
205
204 ## encrypted cookie client side session, good for many instances ##
206 ## encrypted cookie client side session, good for many instances ##
205 #beaker.session.type = cookie
207 #beaker.session.type = cookie
206
208
207 ## file based cookies (default) ##
209 ## file based cookies (default) ##
208 #beaker.session.type = file
210 #beaker.session.type = file
209
211
210
212
211 beaker.session.key = rhodecode
213 beaker.session.key = rhodecode
212 ## secure cookie requires AES python libraries ##
214 ## secure cookie requires AES python libraries ##
213 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
215 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
214 #beaker.session.validate_key = 9712sds2212c--zxc123
216 #beaker.session.validate_key = 9712sds2212c--zxc123
215 ## sets session as invalid if it haven't been accessed for given amount of time
217 ## sets session as invalid if it haven't been accessed for given amount of time
216 beaker.session.timeout = 2592000
218 beaker.session.timeout = 2592000
217 beaker.session.httponly = true
219 beaker.session.httponly = true
218 #beaker.session.cookie_path = /<your-prefix>
220 #beaker.session.cookie_path = /<your-prefix>
219
221
220 ## uncomment for https secure cookie ##
222 ## uncomment for https secure cookie ##
221 beaker.session.secure = false
223 beaker.session.secure = false
222
224
223 ## auto save the session to not to use .save() ##
225 ## auto save the session to not to use .save() ##
224 beaker.session.auto = False
226 beaker.session.auto = False
225
227
226 ## default cookie expiration time in seconds `true` expire at browser close ##
228 ## default cookie expiration time in seconds `true` expire at browser close ##
227 #beaker.session.cookie_expires = 3600
229 #beaker.session.cookie_expires = 3600
228
230
229
231
230 ############################
232 ############################
231 ## ERROR HANDLING SYSTEMS ##
233 ## ERROR HANDLING SYSTEMS ##
232 ############################
234 ############################
233
235
234 ####################
236 ####################
235 ### [errormator] ###
237 ### [errormator] ###
236 ####################
238 ####################
237
239
238 # Errormator is tailored to work with RhodeCode, see
240 # Errormator is tailored to work with RhodeCode, see
239 # http://errormator.com for details how to obtain an account
241 # http://errormator.com for details how to obtain an account
240 # you must install python package `errormator_client` to make it work
242 # you must install python package `errormator_client` to make it work
241
243
242 # errormator enabled
244 # errormator enabled
243 errormator = true
245 errormator = true
244
246
245 errormator.server_url = https://api.errormator.com
247 errormator.server_url = https://api.errormator.com
246 errormator.api_key = YOUR_API_KEY
248 errormator.api_key = YOUR_API_KEY
247
249
248 # TWEAK AMOUNT OF INFO SENT HERE
250 # TWEAK AMOUNT OF INFO SENT HERE
249
251
250 # enables 404 error logging (default False)
252 # enables 404 error logging (default False)
251 errormator.report_404 = false
253 errormator.report_404 = false
252
254
253 # time in seconds after request is considered being slow (default 1)
255 # time in seconds after request is considered being slow (default 1)
254 errormator.slow_request_time = 1
256 errormator.slow_request_time = 1
255
257
256 # record slow requests in application
258 # record slow requests in application
257 # (needs to be enabled for slow datastore recording and time tracking)
259 # (needs to be enabled for slow datastore recording and time tracking)
258 errormator.slow_requests = true
260 errormator.slow_requests = true
259
261
260 # enable hooking to application loggers
262 # enable hooking to application loggers
261 # errormator.logging = true
263 # errormator.logging = true
262
264
263 # minimum log level for log capture
265 # minimum log level for log capture
264 # errormator.logging.level = WARNING
266 # errormator.logging.level = WARNING
265
267
266 # send logs only from erroneous/slow requests
268 # send logs only from erroneous/slow requests
267 # (saves API quota for intensive logging)
269 # (saves API quota for intensive logging)
268 errormator.logging_on_error = false
270 errormator.logging_on_error = false
269
271
270 # list of additonal keywords that should be grabbed from environ object
272 # list of additonal keywords that should be grabbed from environ object
271 # can be string with comma separated list of words in lowercase
273 # can be string with comma separated list of words in lowercase
272 # (by default client will always send following info:
274 # (by default client will always send following info:
273 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
275 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
274 # start with HTTP* this list be extended with additional keywords here
276 # start with HTTP* this list be extended with additional keywords here
275 errormator.environ_keys_whitelist =
277 errormator.environ_keys_whitelist =
276
278
277
279
278 # list of keywords that should be blanked from request object
280 # list of keywords that should be blanked from request object
279 # can be string with comma separated list of words in lowercase
281 # can be string with comma separated list of words in lowercase
280 # (by default client will always blank keys that contain following words
282 # (by default client will always blank keys that contain following words
281 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
283 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
282 # this list be extended with additional keywords set here
284 # this list be extended with additional keywords set here
283 errormator.request_keys_blacklist =
285 errormator.request_keys_blacklist =
284
286
285
287
286 # list of namespaces that should be ignores when gathering log entries
288 # list of namespaces that should be ignores when gathering log entries
287 # can be string with comma separated list of namespaces
289 # can be string with comma separated list of namespaces
288 # (by default the client ignores own entries: errormator_client.client)
290 # (by default the client ignores own entries: errormator_client.client)
289 errormator.log_namespace_blacklist =
291 errormator.log_namespace_blacklist =
290
292
291
293
292 ################
294 ################
293 ### [sentry] ###
295 ### [sentry] ###
294 ################
296 ################
295
297
296 # sentry is a alternative open source error aggregator
298 # sentry is a alternative open source error aggregator
297 # you must install python packages `sentry` and `raven` to enable
299 # you must install python packages `sentry` and `raven` to enable
298
300
299 sentry.dsn = YOUR_DNS
301 sentry.dsn = YOUR_DNS
300 sentry.servers =
302 sentry.servers =
301 sentry.name =
303 sentry.name =
302 sentry.key =
304 sentry.key =
303 sentry.public_key =
305 sentry.public_key =
304 sentry.secret_key =
306 sentry.secret_key =
305 sentry.project =
307 sentry.project =
306 sentry.site =
308 sentry.site =
307 sentry.include_paths =
309 sentry.include_paths =
308 sentry.exclude_paths =
310 sentry.exclude_paths =
309
311
310
312
311 ################################################################################
313 ################################################################################
312 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
314 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
313 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
315 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
314 ## execute malicious code after an exception is raised. ##
316 ## execute malicious code after an exception is raised. ##
315 ################################################################################
317 ################################################################################
316 set debug = false
318 set debug = false
317
319
318 ##################################
320 ##################################
319 ### LOGVIEW CONFIG ###
321 ### LOGVIEW CONFIG ###
320 ##################################
322 ##################################
321 logview.sqlalchemy = #faa
323 logview.sqlalchemy = #faa
322 logview.pylons.templating = #bfb
324 logview.pylons.templating = #bfb
323 logview.pylons.util = #eee
325 logview.pylons.util = #eee
324
326
325 #########################################################
327 #########################################################
326 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
328 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
327 #########################################################
329 #########################################################
328
330
329 # SQLITE [default]
331 # SQLITE [default]
330 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
332 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
331
333
332 # POSTGRESQL
334 # POSTGRESQL
333 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
335 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
334
336
335 # MySQL
337 # MySQL
336 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
338 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
337
339
338 # see sqlalchemy docs for others
340 # see sqlalchemy docs for others
339
341
340 sqlalchemy.db1.echo = false
342 sqlalchemy.db1.echo = false
341 sqlalchemy.db1.pool_recycle = 3600
343 sqlalchemy.db1.pool_recycle = 3600
342 sqlalchemy.db1.convert_unicode = true
344 sqlalchemy.db1.convert_unicode = true
343
345
344 ################################
346 ################################
345 ### LOGGING CONFIGURATION ####
347 ### LOGGING CONFIGURATION ####
346 ################################
348 ################################
347 [loggers]
349 [loggers]
348 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
350 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
349
351
350 [handlers]
352 [handlers]
351 keys = console, console_sql
353 keys = console, console_sql
352
354
353 [formatters]
355 [formatters]
354 keys = generic, color_formatter, color_formatter_sql
356 keys = generic, color_formatter, color_formatter_sql
355
357
356 #############
358 #############
357 ## LOGGERS ##
359 ## LOGGERS ##
358 #############
360 #############
359 [logger_root]
361 [logger_root]
360 level = NOTSET
362 level = NOTSET
361 handlers = console
363 handlers = console
362
364
363 [logger_routes]
365 [logger_routes]
364 level = DEBUG
366 level = DEBUG
365 handlers =
367 handlers =
366 qualname = routes.middleware
368 qualname = routes.middleware
367 # "level = DEBUG" logs the route matched and routing variables.
369 # "level = DEBUG" logs the route matched and routing variables.
368 propagate = 1
370 propagate = 1
369
371
370 [logger_beaker]
372 [logger_beaker]
371 level = DEBUG
373 level = DEBUG
372 handlers =
374 handlers =
373 qualname = beaker.container
375 qualname = beaker.container
374 propagate = 1
376 propagate = 1
375
377
376 [logger_templates]
378 [logger_templates]
377 level = INFO
379 level = INFO
378 handlers =
380 handlers =
379 qualname = pylons.templating
381 qualname = pylons.templating
380 propagate = 1
382 propagate = 1
381
383
382 [logger_rhodecode]
384 [logger_rhodecode]
383 level = DEBUG
385 level = DEBUG
384 handlers =
386 handlers =
385 qualname = rhodecode
387 qualname = rhodecode
386 propagate = 1
388 propagate = 1
387
389
388 [logger_sqlalchemy]
390 [logger_sqlalchemy]
389 level = INFO
391 level = INFO
390 handlers = console_sql
392 handlers = console_sql
391 qualname = sqlalchemy.engine
393 qualname = sqlalchemy.engine
392 propagate = 0
394 propagate = 0
393
395
394 [logger_whoosh_indexer]
396 [logger_whoosh_indexer]
395 level = DEBUG
397 level = DEBUG
396 handlers =
398 handlers =
397 qualname = whoosh_indexer
399 qualname = whoosh_indexer
398 propagate = 1
400 propagate = 1
399
401
400 ##############
402 ##############
401 ## HANDLERS ##
403 ## HANDLERS ##
402 ##############
404 ##############
403
405
404 [handler_console]
406 [handler_console]
405 class = StreamHandler
407 class = StreamHandler
406 args = (sys.stderr,)
408 args = (sys.stderr,)
407 level = INFO
409 level = INFO
408 formatter = generic
410 formatter = generic
409
411
410 [handler_console_sql]
412 [handler_console_sql]
411 class = StreamHandler
413 class = StreamHandler
412 args = (sys.stderr,)
414 args = (sys.stderr,)
413 level = WARN
415 level = WARN
414 formatter = generic
416 formatter = generic
415
417
416 ################
418 ################
417 ## FORMATTERS ##
419 ## FORMATTERS ##
418 ################
420 ################
419
421
420 [formatter_generic]
422 [formatter_generic]
421 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
423 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
422 datefmt = %Y-%m-%d %H:%M:%S
424 datefmt = %Y-%m-%d %H:%M:%S
423
425
424 [formatter_color_formatter]
426 [formatter_color_formatter]
425 class=rhodecode.lib.colored_formatter.ColorFormatter
427 class=rhodecode.lib.colored_formatter.ColorFormatter
426 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
428 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
427 datefmt = %Y-%m-%d %H:%M:%S
429 datefmt = %Y-%m-%d %H:%M:%S
428
430
429 [formatter_color_formatter_sql]
431 [formatter_color_formatter_sql]
430 class=rhodecode.lib.colored_formatter.ColorFormatterSql
432 class=rhodecode.lib.colored_formatter.ColorFormatterSql
431 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
433 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
432 datefmt = %Y-%m-%d %H:%M:%S
434 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,525 +1,557 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.utils
3 rhodecode.lib.utils
4 ~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~
5
5
6 Some simple helper functions
6 Some simple helper functions
7
7
8 :created_on: Jan 5, 2011
8 :created_on: Jan 5, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-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 re
26 import re
27 import time
27 import time
28 import datetime
28 import datetime
29 import webob
29 import webob
30
30
31 from pylons.i18n.translation import _, ungettext
31 from pylons.i18n.translation import _, ungettext
32 from rhodecode.lib.vcs.utils.lazy import LazyProperty
32 from rhodecode.lib.vcs.utils.lazy import LazyProperty
33
33
34
34
35 def __get_lem():
35 def __get_lem():
36 """
36 """
37 Get language extension map based on what's inside pygments lexers
37 Get language extension map based on what's inside pygments lexers
38 """
38 """
39 from pygments import lexers
39 from pygments import lexers
40 from string import lower
40 from string import lower
41 from collections import defaultdict
41 from collections import defaultdict
42
42
43 d = defaultdict(lambda: [])
43 d = defaultdict(lambda: [])
44
44
45 def __clean(s):
45 def __clean(s):
46 s = s.lstrip('*')
46 s = s.lstrip('*')
47 s = s.lstrip('.')
47 s = s.lstrip('.')
48
48
49 if s.find('[') != -1:
49 if s.find('[') != -1:
50 exts = []
50 exts = []
51 start, stop = s.find('['), s.find(']')
51 start, stop = s.find('['), s.find(']')
52
52
53 for suffix in s[start + 1:stop]:
53 for suffix in s[start + 1:stop]:
54 exts.append(s[:s.find('[')] + suffix)
54 exts.append(s[:s.find('[')] + suffix)
55 return map(lower, exts)
55 return map(lower, exts)
56 else:
56 else:
57 return map(lower, [s])
57 return map(lower, [s])
58
58
59 for lx, t in sorted(lexers.LEXERS.items()):
59 for lx, t in sorted(lexers.LEXERS.items()):
60 m = map(__clean, t[-2])
60 m = map(__clean, t[-2])
61 if m:
61 if m:
62 m = reduce(lambda x, y: x + y, m)
62 m = reduce(lambda x, y: x + y, m)
63 for ext in m:
63 for ext in m:
64 desc = lx.replace('Lexer', '')
64 desc = lx.replace('Lexer', '')
65 d[ext].append(desc)
65 d[ext].append(desc)
66
66
67 return dict(d)
67 return dict(d)
68
68
69
69 def str2bool(_str):
70 def str2bool(_str):
70 """
71 """
71 returs True/False value from given string, it tries to translate the
72 returs True/False value from given string, it tries to translate the
72 string into boolean
73 string into boolean
73
74
74 :param _str: string value to translate into boolean
75 :param _str: string value to translate into boolean
75 :rtype: boolean
76 :rtype: boolean
76 :returns: boolean from given string
77 :returns: boolean from given string
77 """
78 """
78 if _str is None:
79 if _str is None:
79 return False
80 return False
80 if _str in (True, False):
81 if _str in (True, False):
81 return _str
82 return _str
82 _str = str(_str).strip().lower()
83 _str = str(_str).strip().lower()
83 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
84 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
84
85
85
86
87 def aslist(obj, sep=None, strip=True):
88 """
89 Returns given string separated by sep as list
90
91 :param obj:
92 :param sep:
93 :param strip:
94 """
95 if isinstance(obj, (basestring)):
96 lst = obj.split(sep)
97 if strip:
98 lst = [v.strip() for v in lst]
99 return lst
100 elif isinstance(obj, (list, tuple)):
101 return obj
102 elif obj is None:
103 return []
104 else:
105 return [obj]
106
107
86 def convert_line_endings(line, mode):
108 def convert_line_endings(line, mode):
87 """
109 """
88 Converts a given line "line end" accordingly to given mode
110 Converts a given line "line end" accordingly to given mode
89
111
90 Available modes are::
112 Available modes are::
91 0 - Unix
113 0 - Unix
92 1 - Mac
114 1 - Mac
93 2 - DOS
115 2 - DOS
94
116
95 :param line: given line to convert
117 :param line: given line to convert
96 :param mode: mode to convert to
118 :param mode: mode to convert to
97 :rtype: str
119 :rtype: str
98 :return: converted line according to mode
120 :return: converted line according to mode
99 """
121 """
100 from string import replace
122 from string import replace
101
123
102 if mode == 0:
124 if mode == 0:
103 line = replace(line, '\r\n', '\n')
125 line = replace(line, '\r\n', '\n')
104 line = replace(line, '\r', '\n')
126 line = replace(line, '\r', '\n')
105 elif mode == 1:
127 elif mode == 1:
106 line = replace(line, '\r\n', '\r')
128 line = replace(line, '\r\n', '\r')
107 line = replace(line, '\n', '\r')
129 line = replace(line, '\n', '\r')
108 elif mode == 2:
130 elif mode == 2:
109 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line)
131 line = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", line)
110 return line
132 return line
111
133
112
134
113 def detect_mode(line, default):
135 def detect_mode(line, default):
114 """
136 """
115 Detects line break for given line, if line break couldn't be found
137 Detects line break for given line, if line break couldn't be found
116 given default value is returned
138 given default value is returned
117
139
118 :param line: str line
140 :param line: str line
119 :param default: default
141 :param default: default
120 :rtype: int
142 :rtype: int
121 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
143 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
122 """
144 """
123 if line.endswith('\r\n'):
145 if line.endswith('\r\n'):
124 return 2
146 return 2
125 elif line.endswith('\n'):
147 elif line.endswith('\n'):
126 return 0
148 return 0
127 elif line.endswith('\r'):
149 elif line.endswith('\r'):
128 return 1
150 return 1
129 else:
151 else:
130 return default
152 return default
131
153
132
154
133 def generate_api_key(username, salt=None):
155 def generate_api_key(username, salt=None):
134 """
156 """
135 Generates unique API key for given username, if salt is not given
157 Generates unique API key for given username, if salt is not given
136 it'll be generated from some random string
158 it'll be generated from some random string
137
159
138 :param username: username as string
160 :param username: username as string
139 :param salt: salt to hash generate KEY
161 :param salt: salt to hash generate KEY
140 :rtype: str
162 :rtype: str
141 :returns: sha1 hash from username+salt
163 :returns: sha1 hash from username+salt
142 """
164 """
143 from tempfile import _RandomNameSequence
165 from tempfile import _RandomNameSequence
144 import hashlib
166 import hashlib
145
167
146 if salt is None:
168 if salt is None:
147 salt = _RandomNameSequence().next()
169 salt = _RandomNameSequence().next()
148
170
149 return hashlib.sha1(username + salt).hexdigest()
171 return hashlib.sha1(username + salt).hexdigest()
150
172
151
173
152 def safe_int(val, default=None):
174 def safe_int(val, default=None):
153 """
175 """
154 Returns int() of val if val is not convertable to int use default
176 Returns int() of val if val is not convertable to int use default
155 instead
177 instead
156
178
157 :param val:
179 :param val:
158 :param default:
180 :param default:
159 """
181 """
160
182
161 try:
183 try:
162 val = int(val)
184 val = int(val)
163 except ValueError:
185 except ValueError:
164 val = default
186 val = default
165
187
166 return val
188 return val
167
189
168
190
169 def safe_unicode(str_, from_encoding=None):
191 def safe_unicode(str_, from_encoding=None):
170 """
192 """
171 safe unicode function. Does few trick to turn str_ into unicode
193 safe unicode function. Does few trick to turn str_ into unicode
172
194
173 In case of UnicodeDecode error we try to return it with encoding detected
195 In case of UnicodeDecode error we try to return it with encoding detected
174 by chardet library if it fails fallback to unicode with errors replaced
196 by chardet library if it fails fallback to unicode with errors replaced
175
197
176 :param str_: string to decode
198 :param str_: string to decode
177 :rtype: unicode
199 :rtype: unicode
178 :returns: unicode object
200 :returns: unicode object
179 """
201 """
180 if isinstance(str_, unicode):
202 if isinstance(str_, unicode):
181 return str_
203 return str_
182
204
183 if not from_encoding:
205 if not from_encoding:
184 import rhodecode
206 import rhodecode
185 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
207 DEFAULT_ENCODINGS = aslist(rhodecode.CONFIG.get('default_encoding',
186 from_encoding = DEFAULT_ENCODING
208 'utf8'), sep=',')
209 from_encoding = DEFAULT_ENCODINGS
210
211 if not isinstance(from_encoding, (list, tuple)):
212 from_encoding = [from_encoding]
187
213
188 try:
214 try:
189 return unicode(str_)
215 return unicode(str_)
190 except UnicodeDecodeError:
216 except UnicodeDecodeError:
191 pass
217 pass
192
218
193 try:
219 for enc in from_encoding:
194 return unicode(str_, from_encoding)
220 try:
195 except UnicodeDecodeError:
221 return unicode(str_, enc)
196 pass
222 except UnicodeDecodeError:
223 pass
197
224
198 try:
225 try:
199 import chardet
226 import chardet
200 encoding = chardet.detect(str_)['encoding']
227 encoding = chardet.detect(str_)['encoding']
201 if encoding is None:
228 if encoding is None:
202 raise Exception()
229 raise Exception()
203 return str_.decode(encoding)
230 return str_.decode(encoding)
204 except (ImportError, UnicodeDecodeError, Exception):
231 except (ImportError, UnicodeDecodeError, Exception):
205 return unicode(str_, from_encoding, 'replace')
232 return unicode(str_, from_encoding[0], 'replace')
206
233
207
234
208 def safe_str(unicode_, to_encoding=None):
235 def safe_str(unicode_, to_encoding=None):
209 """
236 """
210 safe str function. Does few trick to turn unicode_ into string
237 safe str function. Does few trick to turn unicode_ into string
211
238
212 In case of UnicodeEncodeError we try to return it with encoding detected
239 In case of UnicodeEncodeError we try to return it with encoding detected
213 by chardet library if it fails fallback to string with errors replaced
240 by chardet library if it fails fallback to string with errors replaced
214
241
215 :param unicode_: unicode to encode
242 :param unicode_: unicode to encode
216 :rtype: str
243 :rtype: str
217 :returns: str object
244 :returns: str object
218 """
245 """
219
246
220 # if it's not basestr cast to str
247 # if it's not basestr cast to str
221 if not isinstance(unicode_, basestring):
248 if not isinstance(unicode_, basestring):
222 return str(unicode_)
249 return str(unicode_)
223
250
224 if isinstance(unicode_, str):
251 if isinstance(unicode_, str):
225 return unicode_
252 return unicode_
226
253
227 if not to_encoding:
254 if not to_encoding:
228 import rhodecode
255 import rhodecode
229 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding','utf8')
256 DEFAULT_ENCODINGS = aslist(rhodecode.CONFIG.get('default_encoding',
230 to_encoding = DEFAULT_ENCODING
257 'utf8'), sep=',')
258 to_encoding = DEFAULT_ENCODINGS
231
259
232 try:
260 if not isinstance(to_encoding, (list, tuple)):
233 return unicode_.encode(to_encoding)
261 to_encoding = [to_encoding]
234 except UnicodeEncodeError:
262
235 pass
263 for enc in to_encoding:
264 try:
265 return unicode_.encode(enc)
266 except UnicodeEncodeError:
267 pass
236
268
237 try:
269 try:
238 import chardet
270 import chardet
239 encoding = chardet.detect(unicode_)['encoding']
271 encoding = chardet.detect(unicode_)['encoding']
240 if encoding is None:
272 if encoding is None:
241 raise UnicodeEncodeError()
273 raise UnicodeEncodeError()
242
274
243 return unicode_.encode(encoding)
275 return unicode_.encode(encoding)
244 except (ImportError, UnicodeEncodeError):
276 except (ImportError, UnicodeEncodeError):
245 return unicode_.encode(to_encoding, 'replace')
277 return unicode_.encode(to_encoding[0], 'replace')
246
278
247 return safe_str
279 return safe_str
248
280
249
281
250 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
282 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
251 """
283 """
252 Custom engine_from_config functions that makes sure we use NullPool for
284 Custom engine_from_config functions that makes sure we use NullPool for
253 file based sqlite databases. This prevents errors on sqlite. This only
285 file based sqlite databases. This prevents errors on sqlite. This only
254 applies to sqlalchemy versions < 0.7.0
286 applies to sqlalchemy versions < 0.7.0
255
287
256 """
288 """
257 import sqlalchemy
289 import sqlalchemy
258 from sqlalchemy import engine_from_config as efc
290 from sqlalchemy import engine_from_config as efc
259 import logging
291 import logging
260
292
261 if int(sqlalchemy.__version__.split('.')[1]) < 7:
293 if int(sqlalchemy.__version__.split('.')[1]) < 7:
262
294
263 # This solution should work for sqlalchemy < 0.7.0, and should use
295 # This solution should work for sqlalchemy < 0.7.0, and should use
264 # proxy=TimerProxy() for execution time profiling
296 # proxy=TimerProxy() for execution time profiling
265
297
266 from sqlalchemy.pool import NullPool
298 from sqlalchemy.pool import NullPool
267 url = configuration[prefix + 'url']
299 url = configuration[prefix + 'url']
268
300
269 if url.startswith('sqlite'):
301 if url.startswith('sqlite'):
270 kwargs.update({'poolclass': NullPool})
302 kwargs.update({'poolclass': NullPool})
271 return efc(configuration, prefix, **kwargs)
303 return efc(configuration, prefix, **kwargs)
272 else:
304 else:
273 import time
305 import time
274 from sqlalchemy import event
306 from sqlalchemy import event
275 from sqlalchemy.engine import Engine
307 from sqlalchemy.engine import Engine
276
308
277 log = logging.getLogger('sqlalchemy.engine')
309 log = logging.getLogger('sqlalchemy.engine')
278 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
310 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
279 engine = efc(configuration, prefix, **kwargs)
311 engine = efc(configuration, prefix, **kwargs)
280
312
281 def color_sql(sql):
313 def color_sql(sql):
282 COLOR_SEQ = "\033[1;%dm"
314 COLOR_SEQ = "\033[1;%dm"
283 COLOR_SQL = YELLOW
315 COLOR_SQL = YELLOW
284 normal = '\x1b[0m'
316 normal = '\x1b[0m'
285 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
317 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
286
318
287 if configuration['debug']:
319 if configuration['debug']:
288 #attach events only for debug configuration
320 #attach events only for debug configuration
289
321
290 def before_cursor_execute(conn, cursor, statement,
322 def before_cursor_execute(conn, cursor, statement,
291 parameters, context, executemany):
323 parameters, context, executemany):
292 context._query_start_time = time.time()
324 context._query_start_time = time.time()
293 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
325 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
294
326
295 def after_cursor_execute(conn, cursor, statement,
327 def after_cursor_execute(conn, cursor, statement,
296 parameters, context, executemany):
328 parameters, context, executemany):
297 total = time.time() - context._query_start_time
329 total = time.time() - context._query_start_time
298 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
330 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
299
331
300 event.listen(engine, "before_cursor_execute",
332 event.listen(engine, "before_cursor_execute",
301 before_cursor_execute)
333 before_cursor_execute)
302 event.listen(engine, "after_cursor_execute",
334 event.listen(engine, "after_cursor_execute",
303 after_cursor_execute)
335 after_cursor_execute)
304
336
305 return engine
337 return engine
306
338
307
339
308 def age(prevdate):
340 def age(prevdate):
309 """
341 """
310 turns a datetime into an age string.
342 turns a datetime into an age string.
311
343
312 :param prevdate: datetime object
344 :param prevdate: datetime object
313 :rtype: unicode
345 :rtype: unicode
314 :returns: unicode words describing age
346 :returns: unicode words describing age
315 """
347 """
316
348
317 order = ['year', 'month', 'day', 'hour', 'minute', 'second']
349 order = ['year', 'month', 'day', 'hour', 'minute', 'second']
318 deltas = {}
350 deltas = {}
319 future = False
351 future = False
320
352
321 # Get date parts deltas
353 # Get date parts deltas
322 now = datetime.datetime.now()
354 now = datetime.datetime.now()
323 if prevdate > now:
355 if prevdate > now:
324 now, prevdate = prevdate, now
356 now, prevdate = prevdate, now
325 future = True
357 future = True
326
358
327 for part in order:
359 for part in order:
328 deltas[part] = getattr(now, part) - getattr(prevdate, part)
360 deltas[part] = getattr(now, part) - getattr(prevdate, part)
329
361
330 # Fix negative offsets (there is 1 second between 10:59:59 and 11:00:00,
362 # Fix negative offsets (there is 1 second between 10:59:59 and 11:00:00,
331 # not 1 hour, -59 minutes and -59 seconds)
363 # not 1 hour, -59 minutes and -59 seconds)
332
364
333 for num, length in [(5, 60), (4, 60), (3, 24)]: # seconds, minutes, hours
365 for num, length in [(5, 60), (4, 60), (3, 24)]: # seconds, minutes, hours
334 part = order[num]
366 part = order[num]
335 carry_part = order[num - 1]
367 carry_part = order[num - 1]
336
368
337 if deltas[part] < 0:
369 if deltas[part] < 0:
338 deltas[part] += length
370 deltas[part] += length
339 deltas[carry_part] -= 1
371 deltas[carry_part] -= 1
340
372
341 # Same thing for days except that the increment depends on the (variable)
373 # Same thing for days except that the increment depends on the (variable)
342 # number of days in the month
374 # number of days in the month
343 month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
375 month_lengths = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
344 if deltas['day'] < 0:
376 if deltas['day'] < 0:
345 if prevdate.month == 2 and (prevdate.year % 4 == 0 and
377 if prevdate.month == 2 and (prevdate.year % 4 == 0 and
346 (prevdate.year % 100 != 0 or prevdate.year % 400 == 0)):
378 (prevdate.year % 100 != 0 or prevdate.year % 400 == 0)):
347 deltas['day'] += 29
379 deltas['day'] += 29
348 else:
380 else:
349 deltas['day'] += month_lengths[prevdate.month - 1]
381 deltas['day'] += month_lengths[prevdate.month - 1]
350
382
351 deltas['month'] -= 1
383 deltas['month'] -= 1
352
384
353 if deltas['month'] < 0:
385 if deltas['month'] < 0:
354 deltas['month'] += 12
386 deltas['month'] += 12
355 deltas['year'] -= 1
387 deltas['year'] -= 1
356
388
357 # Format the result
389 # Format the result
358 fmt_funcs = {
390 fmt_funcs = {
359 'year': lambda d: ungettext(u'%d year', '%d years', d) % d,
391 'year': lambda d: ungettext(u'%d year', '%d years', d) % d,
360 'month': lambda d: ungettext(u'%d month', '%d months', d) % d,
392 'month': lambda d: ungettext(u'%d month', '%d months', d) % d,
361 'day': lambda d: ungettext(u'%d day', '%d days', d) % d,
393 'day': lambda d: ungettext(u'%d day', '%d days', d) % d,
362 'hour': lambda d: ungettext(u'%d hour', '%d hours', d) % d,
394 'hour': lambda d: ungettext(u'%d hour', '%d hours', d) % d,
363 'minute': lambda d: ungettext(u'%d minute', '%d minutes', d) % d,
395 'minute': lambda d: ungettext(u'%d minute', '%d minutes', d) % d,
364 'second': lambda d: ungettext(u'%d second', '%d seconds', d) % d,
396 'second': lambda d: ungettext(u'%d second', '%d seconds', d) % d,
365 }
397 }
366
398
367 for i, part in enumerate(order):
399 for i, part in enumerate(order):
368 value = deltas[part]
400 value = deltas[part]
369 if value == 0:
401 if value == 0:
370 continue
402 continue
371
403
372 if i < 5:
404 if i < 5:
373 sub_part = order[i + 1]
405 sub_part = order[i + 1]
374 sub_value = deltas[sub_part]
406 sub_value = deltas[sub_part]
375 else:
407 else:
376 sub_value = 0
408 sub_value = 0
377
409
378 if sub_value == 0:
410 if sub_value == 0:
379 if future:
411 if future:
380 return _(u'in %s') % fmt_funcs[part](value)
412 return _(u'in %s') % fmt_funcs[part](value)
381 else:
413 else:
382 return _(u'%s ago') % fmt_funcs[part](value)
414 return _(u'%s ago') % fmt_funcs[part](value)
383 if future:
415 if future:
384 return _(u'in %s and %s') % (fmt_funcs[part](value),
416 return _(u'in %s and %s') % (fmt_funcs[part](value),
385 fmt_funcs[sub_part](sub_value))
417 fmt_funcs[sub_part](sub_value))
386 else:
418 else:
387 return _(u'%s and %s ago') % (fmt_funcs[part](value),
419 return _(u'%s and %s ago') % (fmt_funcs[part](value),
388 fmt_funcs[sub_part](sub_value))
420 fmt_funcs[sub_part](sub_value))
389
421
390 return _(u'just now')
422 return _(u'just now')
391
423
392
424
393 def uri_filter(uri):
425 def uri_filter(uri):
394 """
426 """
395 Removes user:password from given url string
427 Removes user:password from given url string
396
428
397 :param uri:
429 :param uri:
398 :rtype: unicode
430 :rtype: unicode
399 :returns: filtered list of strings
431 :returns: filtered list of strings
400 """
432 """
401 if not uri:
433 if not uri:
402 return ''
434 return ''
403
435
404 proto = ''
436 proto = ''
405
437
406 for pat in ('https://', 'http://'):
438 for pat in ('https://', 'http://'):
407 if uri.startswith(pat):
439 if uri.startswith(pat):
408 uri = uri[len(pat):]
440 uri = uri[len(pat):]
409 proto = pat
441 proto = pat
410 break
442 break
411
443
412 # remove passwords and username
444 # remove passwords and username
413 uri = uri[uri.find('@') + 1:]
445 uri = uri[uri.find('@') + 1:]
414
446
415 # get the port
447 # get the port
416 cred_pos = uri.find(':')
448 cred_pos = uri.find(':')
417 if cred_pos == -1:
449 if cred_pos == -1:
418 host, port = uri, None
450 host, port = uri, None
419 else:
451 else:
420 host, port = uri[:cred_pos], uri[cred_pos + 1:]
452 host, port = uri[:cred_pos], uri[cred_pos + 1:]
421
453
422 return filter(None, [proto, host, port])
454 return filter(None, [proto, host, port])
423
455
424
456
425 def credentials_filter(uri):
457 def credentials_filter(uri):
426 """
458 """
427 Returns a url with removed credentials
459 Returns a url with removed credentials
428
460
429 :param uri:
461 :param uri:
430 """
462 """
431
463
432 uri = uri_filter(uri)
464 uri = uri_filter(uri)
433 #check if we have port
465 #check if we have port
434 if len(uri) > 2 and uri[2]:
466 if len(uri) > 2 and uri[2]:
435 uri[2] = ':' + uri[2]
467 uri[2] = ':' + uri[2]
436
468
437 return ''.join(uri)
469 return ''.join(uri)
438
470
439
471
440 def get_changeset_safe(repo, rev):
472 def get_changeset_safe(repo, rev):
441 """
473 """
442 Safe version of get_changeset if this changeset doesn't exists for a
474 Safe version of get_changeset if this changeset doesn't exists for a
443 repo it returns a Dummy one instead
475 repo it returns a Dummy one instead
444
476
445 :param repo:
477 :param repo:
446 :param rev:
478 :param rev:
447 """
479 """
448 from rhodecode.lib.vcs.backends.base import BaseRepository
480 from rhodecode.lib.vcs.backends.base import BaseRepository
449 from rhodecode.lib.vcs.exceptions import RepositoryError
481 from rhodecode.lib.vcs.exceptions import RepositoryError
450 from rhodecode.lib.vcs.backends.base import EmptyChangeset
482 from rhodecode.lib.vcs.backends.base import EmptyChangeset
451 if not isinstance(repo, BaseRepository):
483 if not isinstance(repo, BaseRepository):
452 raise Exception('You must pass an Repository '
484 raise Exception('You must pass an Repository '
453 'object as first argument got %s', type(repo))
485 'object as first argument got %s', type(repo))
454
486
455 try:
487 try:
456 cs = repo.get_changeset(rev)
488 cs = repo.get_changeset(rev)
457 except RepositoryError:
489 except RepositoryError:
458 cs = EmptyChangeset(requested_revision=rev)
490 cs = EmptyChangeset(requested_revision=rev)
459 return cs
491 return cs
460
492
461
493
462 def datetime_to_time(dt):
494 def datetime_to_time(dt):
463 if dt:
495 if dt:
464 return time.mktime(dt.timetuple())
496 return time.mktime(dt.timetuple())
465
497
466
498
467 def time_to_datetime(tm):
499 def time_to_datetime(tm):
468 if tm:
500 if tm:
469 if isinstance(tm, basestring):
501 if isinstance(tm, basestring):
470 try:
502 try:
471 tm = float(tm)
503 tm = float(tm)
472 except ValueError:
504 except ValueError:
473 return
505 return
474 return datetime.datetime.fromtimestamp(tm)
506 return datetime.datetime.fromtimestamp(tm)
475
507
476 MENTIONS_REGEX = r'(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)(?:\s{1})'
508 MENTIONS_REGEX = r'(?:^@|\s@)([a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+)(?:\s{1})'
477
509
478
510
479 def extract_mentioned_users(s):
511 def extract_mentioned_users(s):
480 """
512 """
481 Returns unique usernames from given string s that have @mention
513 Returns unique usernames from given string s that have @mention
482
514
483 :param s: string to get mentions
515 :param s: string to get mentions
484 """
516 """
485 usrs = set()
517 usrs = set()
486 for username in re.findall(MENTIONS_REGEX, s):
518 for username in re.findall(MENTIONS_REGEX, s):
487 usrs.add(username)
519 usrs.add(username)
488
520
489 return sorted(list(usrs), key=lambda k: k.lower())
521 return sorted(list(usrs), key=lambda k: k.lower())
490
522
491
523
492 class AttributeDict(dict):
524 class AttributeDict(dict):
493 def __getattr__(self, attr):
525 def __getattr__(self, attr):
494 return self.get(attr, None)
526 return self.get(attr, None)
495 __setattr__ = dict.__setitem__
527 __setattr__ = dict.__setitem__
496 __delattr__ = dict.__delitem__
528 __delattr__ = dict.__delitem__
497
529
498
530
499 def fix_PATH(os_=None):
531 def fix_PATH(os_=None):
500 """
532 """
501 Get current active python path, and append it to PATH variable to fix issues
533 Get current active python path, and append it to PATH variable to fix issues
502 of subprocess calls and different python versions
534 of subprocess calls and different python versions
503 """
535 """
504 import sys
536 import sys
505 if os_ is None:
537 if os_ is None:
506 import os
538 import os
507 else:
539 else:
508 os = os_
540 os = os_
509
541
510 cur_path = os.path.split(sys.executable)[0]
542 cur_path = os.path.split(sys.executable)[0]
511 if not os.environ['PATH'].startswith(cur_path):
543 if not os.environ['PATH'].startswith(cur_path):
512 os.environ['PATH'] = '%s:%s' % (cur_path, os.environ['PATH'])
544 os.environ['PATH'] = '%s:%s' % (cur_path, os.environ['PATH'])
513
545
514
546
515 def obfuscate_url_pw(engine):
547 def obfuscate_url_pw(engine):
516 from sqlalchemy.engine import url
548 from sqlalchemy.engine import url
517 url = url.make_url(engine)
549 url = url.make_url(engine)
518 if url.password:
550 if url.password:
519 url.password = 'XXXXX'
551 url.password = 'XXXXX'
520 return str(url)
552 return str(url)
521
553
522
554
523 def get_server_url(environ):
555 def get_server_url(environ):
524 req = webob.Request(environ)
556 req = webob.Request(environ)
525 return req.host_url + req.script_name
557 return req.host_url + req.script_name
@@ -1,138 +1,137 b''
1 """
1 """
2 This module provides some useful tools for ``vcs`` like annotate/diff html
2 This module provides some useful tools for ``vcs`` like annotate/diff html
3 output. It also includes some internal helpers.
3 output. It also includes some internal helpers.
4 """
4 """
5 import sys
5 import sys
6 import time
6 import time
7 import datetime
7 import datetime
8
8
9
9
10 def makedate():
10 def makedate():
11 lt = time.localtime()
11 lt = time.localtime()
12 if lt[8] == 1 and time.daylight:
12 if lt[8] == 1 and time.daylight:
13 tz = time.altzone
13 tz = time.altzone
14 else:
14 else:
15 tz = time.timezone
15 tz = time.timezone
16 return time.mktime(lt), tz
16 return time.mktime(lt), tz
17
17
18
18
19 def date_fromtimestamp(unixts, tzoffset=0):
19 def date_fromtimestamp(unixts, tzoffset=0):
20 """
20 """
21 Makes a local datetime object out of unix timestamp
21 Makes a local datetime object out of unix timestamp
22
22
23 :param unixts:
23 :param unixts:
24 :param tzoffset:
24 :param tzoffset:
25 """
25 """
26
26
27 return datetime.datetime.fromtimestamp(float(unixts))
27 return datetime.datetime.fromtimestamp(float(unixts))
28
28
29
29
30 def safe_unicode(str_, from_encoding=None):
30 def safe_unicode(str_, from_encoding=None):
31 """
31 """
32 safe unicode function. Does few trick to turn str_ into unicode
32 safe unicode function. Does few trick to turn str_ into unicode
33
33
34 In case of UnicodeDecode error we try to return it with encoding detected
34 In case of UnicodeDecode error we try to return it with encoding detected
35 by chardet library if it fails fallback to unicode with errors replaced
35 by chardet library if it fails fallback to unicode with errors replaced
36
36
37 :param str_: string to decode
37 :param str_: string to decode
38 :rtype: unicode
38 :rtype: unicode
39 :returns: unicode object
39 :returns: unicode object
40 """
40 """
41 from rhodecode.lib.utils2 import safe_unicode
42 return safe_unicode(str_, from_encoding)
43
41 if isinstance(str_, unicode):
44 if isinstance(str_, unicode):
42 return str_
45 return str_
43 if not from_encoding:
46
44 import rhodecode
45 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding', 'utf8')
46 from_encoding = DEFAULT_ENCODING
47 try:
47 try:
48 return unicode(str_)
48 return unicode(str_)
49 except UnicodeDecodeError:
49 except UnicodeDecodeError:
50 pass
50 pass
51
51
52 try:
52 try:
53 return unicode(str_, from_encoding)
53 return unicode(str_, from_encoding)
54 except UnicodeDecodeError:
54 except UnicodeDecodeError:
55 pass
55 pass
56
56
57 try:
57 try:
58 import chardet
58 import chardet
59 encoding = chardet.detect(str_)['encoding']
59 encoding = chardet.detect(str_)['encoding']
60 if encoding is None:
60 if encoding is None:
61 raise Exception()
61 raise Exception()
62 return str_.decode(encoding)
62 return str_.decode(encoding)
63 except (ImportError, UnicodeDecodeError, Exception):
63 except (ImportError, UnicodeDecodeError, Exception):
64 return unicode(str_, from_encoding, 'replace')
64 return unicode(str_, from_encoding, 'replace')
65
65
66
66
67 def safe_str(unicode_, to_encoding=None):
67 def safe_str(unicode_, to_encoding=None):
68 """
68 """
69 safe str function. Does few trick to turn unicode_ into string
69 safe str function. Does few trick to turn unicode_ into string
70
70
71 In case of UnicodeEncodeError we try to return it with encoding detected
71 In case of UnicodeEncodeError we try to return it with encoding detected
72 by chardet library if it fails fallback to string with errors replaced
72 by chardet library if it fails fallback to string with errors replaced
73
73
74 :param unicode_: unicode to encode
74 :param unicode_: unicode to encode
75 :rtype: str
75 :rtype: str
76 :returns: str object
76 :returns: str object
77 """
77 """
78 from rhodecode.lib.utils2 import safe_str
79 return safe_str(unicode_, to_encoding)
78
80
79 if isinstance(unicode_, str):
81 if isinstance(unicode_, str):
80 return unicode_
82 return unicode_
81 if not to_encoding:
83
82 import rhodecode
83 DEFAULT_ENCODING = rhodecode.CONFIG.get('default_encoding', 'utf8')
84 to_encoding = DEFAULT_ENCODING
85 try:
84 try:
86 return unicode_.encode(to_encoding)
85 return unicode_.encode(to_encoding)
87 except UnicodeEncodeError:
86 except UnicodeEncodeError:
88 pass
87 pass
89
88
90 try:
89 try:
91 import chardet
90 import chardet
92 encoding = chardet.detect(unicode_)['encoding']
91 encoding = chardet.detect(unicode_)['encoding']
93 if encoding is None:
92 if encoding is None:
94 raise UnicodeEncodeError()
93 raise UnicodeEncodeError()
95
94
96 return unicode_.encode(encoding)
95 return unicode_.encode(encoding)
97 except (ImportError, UnicodeEncodeError):
96 except (ImportError, UnicodeEncodeError):
98 return unicode_.encode(to_encoding, 'replace')
97 return unicode_.encode(to_encoding, 'replace')
99
98
100 return safe_str
99 return safe_str
101
100
102
101
103 def author_email(author):
102 def author_email(author):
104 """
103 """
105 returns email address of given author.
104 returns email address of given author.
106 If any of <,> sign are found, it fallbacks to regex findall()
105 If any of <,> sign are found, it fallbacks to regex findall()
107 and returns first found result or empty string
106 and returns first found result or empty string
108
107
109 Regex taken from http://www.regular-expressions.info/email.html
108 Regex taken from http://www.regular-expressions.info/email.html
110 """
109 """
111 import re
110 import re
112 r = author.find('>')
111 r = author.find('>')
113 l = author.find('<')
112 l = author.find('<')
114
113
115 if l == -1 or r == -1:
114 if l == -1 or r == -1:
116 # fallback to regex match of email out of a string
115 # fallback to regex match of email out of a string
117 email_re = re.compile(r"""[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!"""
116 email_re = re.compile(r"""[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!"""
118 r"""#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z"""
117 r"""#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z"""
119 r"""0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]"""
118 r"""0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]"""
120 r"""*[a-z0-9])?""", re.IGNORECASE)
119 r"""*[a-z0-9])?""", re.IGNORECASE)
121 m = re.findall(email_re, author)
120 m = re.findall(email_re, author)
122 return m[0] if m else ''
121 return m[0] if m else ''
123
122
124 return author[l + 1:r].strip()
123 return author[l + 1:r].strip()
125
124
126
125
127 def author_name(author):
126 def author_name(author):
128 """
127 """
129 get name of author, or else username.
128 get name of author, or else username.
130 It'll try to find an email in the author string and just cut it off
129 It'll try to find an email in the author string and just cut it off
131 to get the username
130 to get the username
132 """
131 """
133
132
134 if not '@' in author:
133 if not '@' in author:
135 return author
134 return author
136 else:
135 else:
137 return author.replace(author_email(author), '').replace('<', '')\
136 return author.replace(author_email(author), '').replace('<', '')\
138 .replace('>', '').strip()
137 .replace('>', '').strip()
General Comments 0
You need to be logged in to leave comments. Login now