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