##// END OF EJS Templates
config: rename options to show_revision_number and show_sha_length...
Mads Kiilerich -
r3651:659bd922 beta
parent child Browse files
Show More
@@ -1,481 +1,481 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE
32 ## PASTE
33 ## nr of threads to spawn
33 ## nr of threads to spawn
34 #threadpool_workers = 5
34 #threadpool_workers = 5
35
35
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38
38
39 ## option to use threads of process
39 ## option to use threads of process
40 #use_threadpool = true
40 #use_threadpool = true
41
41
42 #use = egg:Paste#http
42 #use = egg:Paste#http
43
43
44 ## WAITRESS
44 ## WAITRESS
45 threads = 5
45 threads = 5
46 ## 100GB
46 ## 100GB
47 max_request_body_size = 107374182400
47 max_request_body_size = 107374182400
48 use = egg:waitress#main
48 use = egg:waitress#main
49
49
50 host = 0.0.0.0
50 host = 0.0.0.0
51 port = 5000
51 port = 5000
52
52
53 ## prefix middleware for rc
53 ## prefix middleware for rc
54 #[filter:proxy-prefix]
54 #[filter:proxy-prefix]
55 #use = egg:PasteDeploy#prefix
55 #use = egg:PasteDeploy#prefix
56 #prefix = /<your-prefix>
56 #prefix = /<your-prefix>
57
57
58 [app:main]
58 [app:main]
59 use = egg:rhodecode
59 use = egg:rhodecode
60 ## enable proxy prefix middleware
60 ## enable proxy prefix middleware
61 #filter-with = proxy-prefix
61 #filter-with = proxy-prefix
62
62
63 full_stack = true
63 full_stack = true
64 static_files = true
64 static_files = true
65 ## Optional Languages
65 ## Optional Languages
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
67 lang = en
67 lang = en
68 cache_dir = %(here)s/data
68 cache_dir = %(here)s/data
69 index_dir = %(here)s/data/index
69 index_dir = %(here)s/data/index
70
70
71 ## uncomment and set this path to use archive download cache
71 ## uncomment and set this path to use archive download cache
72 #archive_cache_dir = /tmp/tarballcache
72 #archive_cache_dir = /tmp/tarballcache
73
73
74 ## change this to unique ID for security
74 ## change this to unique ID for security
75 app_instance_uuid = rc-production
75 app_instance_uuid = rc-production
76
76
77 ## cut off limit for large diffs (size in bytes)
77 ## cut off limit for large diffs (size in bytes)
78 cut_off_limit = 256000
78 cut_off_limit = 256000
79
79
80 ## use cache version of scm repo everywhere
80 ## use cache version of scm repo everywhere
81 vcs_full_cache = true
81 vcs_full_cache = true
82
82
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
84 force_https = false
84 force_https = false
85
85
86 ## use Strict-Transport-Security headers
86 ## use Strict-Transport-Security headers
87 use_htsts = false
87 use_htsts = false
88
88
89 ## number of commits stats will parse on each iteration
89 ## number of commits stats will parse on each iteration
90 commit_parse_limit = 25
90 commit_parse_limit = 25
91
91
92 ## number of items displayed in lightweight dashboard before paginating is shown
92 ## number of items displayed in lightweight dashboard before paginating is shown
93 dashboard_items = 100
93 dashboard_items = 100
94
94
95 ## use gravatar service to display avatars
95 ## use gravatar service to display avatars
96 use_gravatar = true
96 use_gravatar = true
97
97
98 ## path to git executable
98 ## path to git executable
99 git_path = git
99 git_path = git
100
100
101 ## git rev filter option, --all is the default filter, if you need to
101 ## git rev filter option, --all is the default filter, if you need to
102 ## hide all refs in changelog switch this to --branches --tags
102 ## hide all refs in changelog switch this to --branches --tags
103 git_rev_filter=--all
103 git_rev_filter=--all
104
104
105 ## RSS feed options
105 ## RSS feed options
106 rss_cut_off_limit = 256000
106 rss_cut_off_limit = 256000
107 rss_items_per_page = 10
107 rss_items_per_page = 10
108 rss_include_diff = false
108 rss_include_diff = false
109
109
110 ## show hash options for changelog
110 ## options for showing and identifying changesets
111 sha_len = 12
111 show_sha_length = 12
112 sha_show_numeric_rev = true
112 show_revision_number = true
113
113
114
114
115 ## alternative_gravatar_url allows you to use your own avatar server application
115 ## alternative_gravatar_url allows you to use your own avatar server application
116 ## the following parts of the URL will be replaced
116 ## the following parts of the URL will be replaced
117 ## {email} user email
117 ## {email} user email
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
119 ## {size} size of the image that is expected from the server application
119 ## {size} size of the image that is expected from the server application
120 ## {scheme} http/https from RhodeCode server
120 ## {scheme} http/https from RhodeCode server
121 ## {netloc} network location from RhodeCode server
121 ## {netloc} network location from RhodeCode server
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
124
124
125
125
126 ## container auth options
126 ## container auth options
127 container_auth_enabled = false
127 container_auth_enabled = false
128 proxypass_auth_enabled = false
128 proxypass_auth_enabled = false
129
129
130 ## default encoding used to convert from and to unicode
130 ## default encoding used to convert from and to unicode
131 ## can be also a comma seperated list of encoding in case of mixed encodings
131 ## can be also a comma seperated list of encoding in case of mixed encodings
132 default_encoding = utf8
132 default_encoding = utf8
133
133
134 ## overwrite schema of clone url
134 ## overwrite schema of clone url
135 ## available vars:
135 ## available vars:
136 ## scheme - http/https
136 ## scheme - http/https
137 ## user - current user
137 ## user - current user
138 ## pass - password
138 ## pass - password
139 ## netloc - network location
139 ## netloc - network location
140 ## path - usually repo_name
140 ## path - usually repo_name
141
141
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
143
143
144 ## issue tracking mapping for commits messages
144 ## issue tracking mapping for commits messages
145 ## comment out issue_pat, issue_server, issue_prefix to enable
145 ## comment out issue_pat, issue_server, issue_prefix to enable
146
146
147 ## pattern to get the issues from commit messages
147 ## pattern to get the issues from commit messages
148 ## default one used here is #<numbers> with a regex passive group for `#`
148 ## default one used here is #<numbers> with a regex passive group for `#`
149 ## {id} will be all groups matched from this pattern
149 ## {id} will be all groups matched from this pattern
150
150
151 issue_pat = (?:\s*#)(\d+)
151 issue_pat = (?:\s*#)(\d+)
152
152
153 ## server url to the issue, each {id} will be replaced with match
153 ## server url to the issue, each {id} will be replaced with match
154 ## fetched from the regex and {repo} is replaced with full repository name
154 ## fetched from the regex and {repo} is replaced with full repository name
155 ## including groups {repo_name} is replaced with just name of repo
155 ## including groups {repo_name} is replaced with just name of repo
156
156
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
158
158
159 ## prefix to add to link to indicate it's an url
159 ## prefix to add to link to indicate it's an url
160 ## #314 will be replaced by <issue_prefix><id>
160 ## #314 will be replaced by <issue_prefix><id>
161
161
162 issue_prefix = #
162 issue_prefix = #
163
163
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
165 ## multiple patterns, to other issues server, wiki or others
165 ## multiple patterns, to other issues server, wiki or others
166 ## below an example how to create a wiki pattern
166 ## below an example how to create a wiki pattern
167 # #wiki-some-id -> https://mywiki.com/some-id
167 # #wiki-some-id -> https://mywiki.com/some-id
168
168
169 #issue_pat_wiki = (?:wiki-)(.+)
169 #issue_pat_wiki = (?:wiki-)(.+)
170 #issue_server_link_wiki = https://mywiki.com/{id}
170 #issue_server_link_wiki = https://mywiki.com/{id}
171 #issue_prefix_wiki = WIKI-
171 #issue_prefix_wiki = WIKI-
172
172
173
173
174 ## instance-id prefix
174 ## instance-id prefix
175 ## a prefix key for this instance used for cache invalidation when running
175 ## a prefix key for this instance used for cache invalidation when running
176 ## multiple instances of rhodecode, make sure it's globally unique for
176 ## multiple instances of rhodecode, make sure it's globally unique for
177 ## all running rhodecode instances. Leave empty if you don't use it
177 ## all running rhodecode instances. Leave empty if you don't use it
178 instance_id =
178 instance_id =
179
179
180 ## alternative return HTTP header for failed authentication. Default HTTP
180 ## alternative return HTTP header for failed authentication. Default HTTP
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
182 ## handling that. Set this variable to 403 to return HTTPForbidden
182 ## handling that. Set this variable to 403 to return HTTPForbidden
183 auth_ret_code =
183 auth_ret_code =
184
184
185 ## locking return code. When repository is locked return this HTTP code. 2XX
185 ## locking return code. When repository is locked return this HTTP code. 2XX
186 ## codes don't break the transactions while 4XX codes do
186 ## codes don't break the transactions while 4XX codes do
187 lock_ret_code = 423
187 lock_ret_code = 423
188
188
189
189
190 ####################################
190 ####################################
191 ### CELERY CONFIG ####
191 ### CELERY CONFIG ####
192 ####################################
192 ####################################
193 use_celery = false
193 use_celery = false
194 broker.host = localhost
194 broker.host = localhost
195 broker.vhost = rabbitmqhost
195 broker.vhost = rabbitmqhost
196 broker.port = 5672
196 broker.port = 5672
197 broker.user = rabbitmq
197 broker.user = rabbitmq
198 broker.password = qweqwe
198 broker.password = qweqwe
199
199
200 celery.imports = rhodecode.lib.celerylib.tasks
200 celery.imports = rhodecode.lib.celerylib.tasks
201
201
202 celery.result.backend = amqp
202 celery.result.backend = amqp
203 celery.result.dburi = amqp://
203 celery.result.dburi = amqp://
204 celery.result.serialier = json
204 celery.result.serialier = json
205
205
206 #celery.send.task.error.emails = true
206 #celery.send.task.error.emails = true
207 #celery.amqp.task.result.expires = 18000
207 #celery.amqp.task.result.expires = 18000
208
208
209 celeryd.concurrency = 2
209 celeryd.concurrency = 2
210 #celeryd.log.file = celeryd.log
210 #celeryd.log.file = celeryd.log
211 celeryd.log.level = debug
211 celeryd.log.level = debug
212 celeryd.max.tasks.per.child = 1
212 celeryd.max.tasks.per.child = 1
213
213
214 ## tasks will never be sent to the queue, but executed locally instead.
214 ## tasks will never be sent to the queue, but executed locally instead.
215 celery.always.eager = false
215 celery.always.eager = false
216
216
217 ####################################
217 ####################################
218 ### BEAKER CACHE ####
218 ### BEAKER CACHE ####
219 ####################################
219 ####################################
220 beaker.cache.data_dir=%(here)s/data/cache/data
220 beaker.cache.data_dir=%(here)s/data/cache/data
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
222
222
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
224
224
225 beaker.cache.super_short_term.type=memory
225 beaker.cache.super_short_term.type=memory
226 beaker.cache.super_short_term.expire=10
226 beaker.cache.super_short_term.expire=10
227 beaker.cache.super_short_term.key_length = 256
227 beaker.cache.super_short_term.key_length = 256
228
228
229 beaker.cache.short_term.type=memory
229 beaker.cache.short_term.type=memory
230 beaker.cache.short_term.expire=60
230 beaker.cache.short_term.expire=60
231 beaker.cache.short_term.key_length = 256
231 beaker.cache.short_term.key_length = 256
232
232
233 beaker.cache.long_term.type=memory
233 beaker.cache.long_term.type=memory
234 beaker.cache.long_term.expire=36000
234 beaker.cache.long_term.expire=36000
235 beaker.cache.long_term.key_length = 256
235 beaker.cache.long_term.key_length = 256
236
236
237 beaker.cache.sql_cache_short.type=memory
237 beaker.cache.sql_cache_short.type=memory
238 beaker.cache.sql_cache_short.expire=10
238 beaker.cache.sql_cache_short.expire=10
239 beaker.cache.sql_cache_short.key_length = 256
239 beaker.cache.sql_cache_short.key_length = 256
240
240
241 beaker.cache.sql_cache_med.type=memory
241 beaker.cache.sql_cache_med.type=memory
242 beaker.cache.sql_cache_med.expire=360
242 beaker.cache.sql_cache_med.expire=360
243 beaker.cache.sql_cache_med.key_length = 256
243 beaker.cache.sql_cache_med.key_length = 256
244
244
245 beaker.cache.sql_cache_long.type=file
245 beaker.cache.sql_cache_long.type=file
246 beaker.cache.sql_cache_long.expire=3600
246 beaker.cache.sql_cache_long.expire=3600
247 beaker.cache.sql_cache_long.key_length = 256
247 beaker.cache.sql_cache_long.key_length = 256
248
248
249 ####################################
249 ####################################
250 ### BEAKER SESSION ####
250 ### BEAKER SESSION ####
251 ####################################
251 ####################################
252 ## Type of storage used for the session, current types are
252 ## Type of storage used for the session, current types are
253 ## dbm, file, memcached, database, and memory.
253 ## dbm, file, memcached, database, and memory.
254 ## The storage uses the Container API
254 ## The storage uses the Container API
255 ## that is also used by the cache system.
255 ## that is also used by the cache system.
256
256
257 ## db session ##
257 ## db session ##
258 #beaker.session.type = ext:database
258 #beaker.session.type = ext:database
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
260 #beaker.session.table_name = db_session
260 #beaker.session.table_name = db_session
261
261
262 ## encrypted cookie client side session, good for many instances ##
262 ## encrypted cookie client side session, good for many instances ##
263 #beaker.session.type = cookie
263 #beaker.session.type = cookie
264
264
265 ## file based cookies (default) ##
265 ## file based cookies (default) ##
266 #beaker.session.type = file
266 #beaker.session.type = file
267
267
268
268
269 beaker.session.key = rhodecode
269 beaker.session.key = rhodecode
270 ## secure cookie requires AES python libraries
270 ## secure cookie requires AES python libraries
271 #beaker.session.encrypt_key = <key_for_encryption>
271 #beaker.session.encrypt_key = <key_for_encryption>
272 #beaker.session.validate_key = <validation_key>
272 #beaker.session.validate_key = <validation_key>
273
273
274 ## sets session as invalid if it haven't been accessed for given amount of time
274 ## sets session as invalid if it haven't been accessed for given amount of time
275 beaker.session.timeout = 2592000
275 beaker.session.timeout = 2592000
276 beaker.session.httponly = true
276 beaker.session.httponly = true
277 #beaker.session.cookie_path = /<your-prefix>
277 #beaker.session.cookie_path = /<your-prefix>
278
278
279 ## uncomment for https secure cookie
279 ## uncomment for https secure cookie
280 beaker.session.secure = false
280 beaker.session.secure = false
281
281
282 ## auto save the session to not to use .save()
282 ## auto save the session to not to use .save()
283 beaker.session.auto = False
283 beaker.session.auto = False
284
284
285 ## default cookie expiration time in seconds `true` expire at browser close ##
285 ## default cookie expiration time in seconds `true` expire at browser close ##
286 #beaker.session.cookie_expires = 3600
286 #beaker.session.cookie_expires = 3600
287
287
288
288
289 ############################
289 ############################
290 ## ERROR HANDLING SYSTEMS ##
290 ## ERROR HANDLING SYSTEMS ##
291 ############################
291 ############################
292
292
293 ####################
293 ####################
294 ### [errormator] ###
294 ### [errormator] ###
295 ####################
295 ####################
296
296
297 ## Errormator is tailored to work with RhodeCode, see
297 ## Errormator is tailored to work with RhodeCode, see
298 ## http://errormator.com for details how to obtain an account
298 ## http://errormator.com for details how to obtain an account
299 ## you must install python package `errormator_client` to make it work
299 ## you must install python package `errormator_client` to make it work
300
300
301 ## errormator enabled
301 ## errormator enabled
302 errormator = false
302 errormator = false
303
303
304 errormator.server_url = https://api.errormator.com
304 errormator.server_url = https://api.errormator.com
305 errormator.api_key = YOUR_API_KEY
305 errormator.api_key = YOUR_API_KEY
306
306
307 ## TWEAK AMOUNT OF INFO SENT HERE
307 ## TWEAK AMOUNT OF INFO SENT HERE
308
308
309 ## enables 404 error logging (default False)
309 ## enables 404 error logging (default False)
310 errormator.report_404 = false
310 errormator.report_404 = false
311
311
312 ## time in seconds after request is considered being slow (default 1)
312 ## time in seconds after request is considered being slow (default 1)
313 errormator.slow_request_time = 1
313 errormator.slow_request_time = 1
314
314
315 ## record slow requests in application
315 ## record slow requests in application
316 ## (needs to be enabled for slow datastore recording and time tracking)
316 ## (needs to be enabled for slow datastore recording and time tracking)
317 errormator.slow_requests = true
317 errormator.slow_requests = true
318
318
319 ## enable hooking to application loggers
319 ## enable hooking to application loggers
320 # errormator.logging = true
320 # errormator.logging = true
321
321
322 ## minimum log level for log capture
322 ## minimum log level for log capture
323 # errormator.logging.level = WARNING
323 # errormator.logging.level = WARNING
324
324
325 ## send logs only from erroneous/slow requests
325 ## send logs only from erroneous/slow requests
326 ## (saves API quota for intensive logging)
326 ## (saves API quota for intensive logging)
327 errormator.logging_on_error = false
327 errormator.logging_on_error = false
328
328
329 ## list of additonal keywords that should be grabbed from environ object
329 ## list of additonal keywords that should be grabbed from environ object
330 ## can be string with comma separated list of words in lowercase
330 ## can be string with comma separated list of words in lowercase
331 ## (by default client will always send following info:
331 ## (by default client will always send following info:
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
333 ## start with HTTP* this list be extended with additional keywords here
333 ## start with HTTP* this list be extended with additional keywords here
334 errormator.environ_keys_whitelist =
334 errormator.environ_keys_whitelist =
335
335
336
336
337 ## list of keywords that should be blanked from request object
337 ## list of keywords that should be blanked from request object
338 ## can be string with comma separated list of words in lowercase
338 ## can be string with comma separated list of words in lowercase
339 ## (by default client will always blank keys that contain following words
339 ## (by default client will always blank keys that contain following words
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
341 ## this list be extended with additional keywords set here
341 ## this list be extended with additional keywords set here
342 errormator.request_keys_blacklist =
342 errormator.request_keys_blacklist =
343
343
344
344
345 ## list of namespaces that should be ignores when gathering log entries
345 ## list of namespaces that should be ignores when gathering log entries
346 ## can be string with comma separated list of namespaces
346 ## can be string with comma separated list of namespaces
347 ## (by default the client ignores own entries: errormator_client.client)
347 ## (by default the client ignores own entries: errormator_client.client)
348 errormator.log_namespace_blacklist =
348 errormator.log_namespace_blacklist =
349
349
350
350
351 ################
351 ################
352 ### [sentry] ###
352 ### [sentry] ###
353 ################
353 ################
354
354
355 ## sentry is a alternative open source error aggregator
355 ## sentry is a alternative open source error aggregator
356 ## you must install python packages `sentry` and `raven` to enable
356 ## you must install python packages `sentry` and `raven` to enable
357
357
358 sentry.dsn = YOUR_DNS
358 sentry.dsn = YOUR_DNS
359 sentry.servers =
359 sentry.servers =
360 sentry.name =
360 sentry.name =
361 sentry.key =
361 sentry.key =
362 sentry.public_key =
362 sentry.public_key =
363 sentry.secret_key =
363 sentry.secret_key =
364 sentry.project =
364 sentry.project =
365 sentry.site =
365 sentry.site =
366 sentry.include_paths =
366 sentry.include_paths =
367 sentry.exclude_paths =
367 sentry.exclude_paths =
368
368
369
369
370 ################################################################################
370 ################################################################################
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
373 ## execute malicious code after an exception is raised. ##
373 ## execute malicious code after an exception is raised. ##
374 ################################################################################
374 ################################################################################
375 #set debug = false
375 #set debug = false
376
376
377 ##################################
377 ##################################
378 ### LOGVIEW CONFIG ###
378 ### LOGVIEW CONFIG ###
379 ##################################
379 ##################################
380 logview.sqlalchemy = #faa
380 logview.sqlalchemy = #faa
381 logview.pylons.templating = #bfb
381 logview.pylons.templating = #bfb
382 logview.pylons.util = #eee
382 logview.pylons.util = #eee
383
383
384 #########################################################
384 #########################################################
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
386 #########################################################
386 #########################################################
387 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
387 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
388 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
388 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
389 sqlalchemy.db1.echo = false
389 sqlalchemy.db1.echo = false
390 sqlalchemy.db1.pool_recycle = 3600
390 sqlalchemy.db1.pool_recycle = 3600
391 sqlalchemy.db1.convert_unicode = true
391 sqlalchemy.db1.convert_unicode = true
392
392
393 ################################
393 ################################
394 ### LOGGING CONFIGURATION ####
394 ### LOGGING CONFIGURATION ####
395 ################################
395 ################################
396 [loggers]
396 [loggers]
397 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
397 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
398
398
399 [handlers]
399 [handlers]
400 keys = console, console_sql
400 keys = console, console_sql
401
401
402 [formatters]
402 [formatters]
403 keys = generic, color_formatter, color_formatter_sql
403 keys = generic, color_formatter, color_formatter_sql
404
404
405 #############
405 #############
406 ## LOGGERS ##
406 ## LOGGERS ##
407 #############
407 #############
408 [logger_root]
408 [logger_root]
409 level = NOTSET
409 level = NOTSET
410 handlers = console
410 handlers = console
411
411
412 [logger_routes]
412 [logger_routes]
413 level = DEBUG
413 level = DEBUG
414 handlers =
414 handlers =
415 qualname = routes.middleware
415 qualname = routes.middleware
416 ## "level = DEBUG" logs the route matched and routing variables.
416 ## "level = DEBUG" logs the route matched and routing variables.
417 propagate = 1
417 propagate = 1
418
418
419 [logger_beaker]
419 [logger_beaker]
420 level = DEBUG
420 level = DEBUG
421 handlers =
421 handlers =
422 qualname = beaker.container
422 qualname = beaker.container
423 propagate = 1
423 propagate = 1
424
424
425 [logger_templates]
425 [logger_templates]
426 level = INFO
426 level = INFO
427 handlers =
427 handlers =
428 qualname = pylons.templating
428 qualname = pylons.templating
429 propagate = 1
429 propagate = 1
430
430
431 [logger_rhodecode]
431 [logger_rhodecode]
432 level = DEBUG
432 level = DEBUG
433 handlers =
433 handlers =
434 qualname = rhodecode
434 qualname = rhodecode
435 propagate = 1
435 propagate = 1
436
436
437 [logger_sqlalchemy]
437 [logger_sqlalchemy]
438 level = INFO
438 level = INFO
439 handlers = console_sql
439 handlers = console_sql
440 qualname = sqlalchemy.engine
440 qualname = sqlalchemy.engine
441 propagate = 0
441 propagate = 0
442
442
443 [logger_whoosh_indexer]
443 [logger_whoosh_indexer]
444 level = DEBUG
444 level = DEBUG
445 handlers =
445 handlers =
446 qualname = whoosh_indexer
446 qualname = whoosh_indexer
447 propagate = 1
447 propagate = 1
448
448
449 ##############
449 ##############
450 ## HANDLERS ##
450 ## HANDLERS ##
451 ##############
451 ##############
452
452
453 [handler_console]
453 [handler_console]
454 class = StreamHandler
454 class = StreamHandler
455 args = (sys.stderr,)
455 args = (sys.stderr,)
456 level = DEBUG
456 level = DEBUG
457 formatter = color_formatter
457 formatter = color_formatter
458
458
459 [handler_console_sql]
459 [handler_console_sql]
460 class = StreamHandler
460 class = StreamHandler
461 args = (sys.stderr,)
461 args = (sys.stderr,)
462 level = DEBUG
462 level = DEBUG
463 formatter = color_formatter_sql
463 formatter = color_formatter_sql
464
464
465 ################
465 ################
466 ## FORMATTERS ##
466 ## FORMATTERS ##
467 ################
467 ################
468
468
469 [formatter_generic]
469 [formatter_generic]
470 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
470 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
471 datefmt = %Y-%m-%d %H:%M:%S
471 datefmt = %Y-%m-%d %H:%M:%S
472
472
473 [formatter_color_formatter]
473 [formatter_color_formatter]
474 class=rhodecode.lib.colored_formatter.ColorFormatter
474 class=rhodecode.lib.colored_formatter.ColorFormatter
475 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
475 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
476 datefmt = %Y-%m-%d %H:%M:%S
476 datefmt = %Y-%m-%d %H:%M:%S
477
477
478 [formatter_color_formatter_sql]
478 [formatter_color_formatter_sql]
479 class=rhodecode.lib.colored_formatter.ColorFormatterSql
479 class=rhodecode.lib.colored_formatter.ColorFormatterSql
480 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
480 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
481 datefmt = %Y-%m-%d %H:%M:%S
481 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,481 +1,481 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE
32 ## PASTE
33 ## nr of threads to spawn
33 ## nr of threads to spawn
34 #threadpool_workers = 5
34 #threadpool_workers = 5
35
35
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38
38
39 ## option to use threads of process
39 ## option to use threads of process
40 #use_threadpool = true
40 #use_threadpool = true
41
41
42 #use = egg:Paste#http
42 #use = egg:Paste#http
43
43
44 ## WAITRESS
44 ## WAITRESS
45 threads = 5
45 threads = 5
46 ## 100GB
46 ## 100GB
47 max_request_body_size = 107374182400
47 max_request_body_size = 107374182400
48 use = egg:waitress#main
48 use = egg:waitress#main
49
49
50 host = 127.0.0.1
50 host = 127.0.0.1
51 port = 8001
51 port = 8001
52
52
53 ## prefix middleware for rc
53 ## prefix middleware for rc
54 #[filter:proxy-prefix]
54 #[filter:proxy-prefix]
55 #use = egg:PasteDeploy#prefix
55 #use = egg:PasteDeploy#prefix
56 #prefix = /<your-prefix>
56 #prefix = /<your-prefix>
57
57
58 [app:main]
58 [app:main]
59 use = egg:rhodecode
59 use = egg:rhodecode
60 ## enable proxy prefix middleware
60 ## enable proxy prefix middleware
61 #filter-with = proxy-prefix
61 #filter-with = proxy-prefix
62
62
63 full_stack = true
63 full_stack = true
64 static_files = true
64 static_files = true
65 ## Optional Languages
65 ## Optional Languages
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
67 lang = en
67 lang = en
68 cache_dir = %(here)s/data
68 cache_dir = %(here)s/data
69 index_dir = %(here)s/data/index
69 index_dir = %(here)s/data/index
70
70
71 ## uncomment and set this path to use archive download cache
71 ## uncomment and set this path to use archive download cache
72 #archive_cache_dir = /tmp/tarballcache
72 #archive_cache_dir = /tmp/tarballcache
73
73
74 ## change this to unique ID for security
74 ## change this to unique ID for security
75 app_instance_uuid = rc-production
75 app_instance_uuid = rc-production
76
76
77 ## cut off limit for large diffs (size in bytes)
77 ## cut off limit for large diffs (size in bytes)
78 cut_off_limit = 256000
78 cut_off_limit = 256000
79
79
80 ## use cache version of scm repo everywhere
80 ## use cache version of scm repo everywhere
81 vcs_full_cache = true
81 vcs_full_cache = true
82
82
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
84 force_https = false
84 force_https = false
85
85
86 ## use Strict-Transport-Security headers
86 ## use Strict-Transport-Security headers
87 use_htsts = false
87 use_htsts = false
88
88
89 ## number of commits stats will parse on each iteration
89 ## number of commits stats will parse on each iteration
90 commit_parse_limit = 25
90 commit_parse_limit = 25
91
91
92 ## number of items displayed in lightweight dashboard before paginating is shown
92 ## number of items displayed in lightweight dashboard before paginating is shown
93 dashboard_items = 100
93 dashboard_items = 100
94
94
95 ## use gravatar service to display avatars
95 ## use gravatar service to display avatars
96 use_gravatar = true
96 use_gravatar = true
97
97
98 ## path to git executable
98 ## path to git executable
99 git_path = git
99 git_path = git
100
100
101 ## git rev filter option, --all is the default filter, if you need to
101 ## git rev filter option, --all is the default filter, if you need to
102 ## hide all refs in changelog switch this to --branches --tags
102 ## hide all refs in changelog switch this to --branches --tags
103 git_rev_filter=--all
103 git_rev_filter=--all
104
104
105 ## RSS feed options
105 ## RSS feed options
106 rss_cut_off_limit = 256000
106 rss_cut_off_limit = 256000
107 rss_items_per_page = 10
107 rss_items_per_page = 10
108 rss_include_diff = false
108 rss_include_diff = false
109
109
110 ## show hash options for changelog
110 ## options for showing and identifying changesets
111 sha_len = 12
111 show_sha_length = 12
112 sha_show_numeric_rev = true
112 show_revision_number = true
113
113
114
114
115 ## alternative_gravatar_url allows you to use your own avatar server application
115 ## alternative_gravatar_url allows you to use your own avatar server application
116 ## the following parts of the URL will be replaced
116 ## the following parts of the URL will be replaced
117 ## {email} user email
117 ## {email} user email
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
119 ## {size} size of the image that is expected from the server application
119 ## {size} size of the image that is expected from the server application
120 ## {scheme} http/https from RhodeCode server
120 ## {scheme} http/https from RhodeCode server
121 ## {netloc} network location from RhodeCode server
121 ## {netloc} network location from RhodeCode server
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
124
124
125
125
126 ## container auth options
126 ## container auth options
127 container_auth_enabled = false
127 container_auth_enabled = false
128 proxypass_auth_enabled = false
128 proxypass_auth_enabled = false
129
129
130 ## default encoding used to convert from and to unicode
130 ## default encoding used to convert from and to unicode
131 ## can be also a comma seperated list of encoding in case of mixed encodings
131 ## can be also a comma seperated list of encoding in case of mixed encodings
132 default_encoding = utf8
132 default_encoding = utf8
133
133
134 ## overwrite schema of clone url
134 ## overwrite schema of clone url
135 ## available vars:
135 ## available vars:
136 ## scheme - http/https
136 ## scheme - http/https
137 ## user - current user
137 ## user - current user
138 ## pass - password
138 ## pass - password
139 ## netloc - network location
139 ## netloc - network location
140 ## path - usually repo_name
140 ## path - usually repo_name
141
141
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
143
143
144 ## issue tracking mapping for commits messages
144 ## issue tracking mapping for commits messages
145 ## comment out issue_pat, issue_server, issue_prefix to enable
145 ## comment out issue_pat, issue_server, issue_prefix to enable
146
146
147 ## pattern to get the issues from commit messages
147 ## pattern to get the issues from commit messages
148 ## default one used here is #<numbers> with a regex passive group for `#`
148 ## default one used here is #<numbers> with a regex passive group for `#`
149 ## {id} will be all groups matched from this pattern
149 ## {id} will be all groups matched from this pattern
150
150
151 issue_pat = (?:\s*#)(\d+)
151 issue_pat = (?:\s*#)(\d+)
152
152
153 ## server url to the issue, each {id} will be replaced with match
153 ## server url to the issue, each {id} will be replaced with match
154 ## fetched from the regex and {repo} is replaced with full repository name
154 ## fetched from the regex and {repo} is replaced with full repository name
155 ## including groups {repo_name} is replaced with just name of repo
155 ## including groups {repo_name} is replaced with just name of repo
156
156
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
158
158
159 ## prefix to add to link to indicate it's an url
159 ## prefix to add to link to indicate it's an url
160 ## #314 will be replaced by <issue_prefix><id>
160 ## #314 will be replaced by <issue_prefix><id>
161
161
162 issue_prefix = #
162 issue_prefix = #
163
163
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
165 ## multiple patterns, to other issues server, wiki or others
165 ## multiple patterns, to other issues server, wiki or others
166 ## below an example how to create a wiki pattern
166 ## below an example how to create a wiki pattern
167 # #wiki-some-id -> https://mywiki.com/some-id
167 # #wiki-some-id -> https://mywiki.com/some-id
168
168
169 #issue_pat_wiki = (?:wiki-)(.+)
169 #issue_pat_wiki = (?:wiki-)(.+)
170 #issue_server_link_wiki = https://mywiki.com/{id}
170 #issue_server_link_wiki = https://mywiki.com/{id}
171 #issue_prefix_wiki = WIKI-
171 #issue_prefix_wiki = WIKI-
172
172
173
173
174 ## instance-id prefix
174 ## instance-id prefix
175 ## a prefix key for this instance used for cache invalidation when running
175 ## a prefix key for this instance used for cache invalidation when running
176 ## multiple instances of rhodecode, make sure it's globally unique for
176 ## multiple instances of rhodecode, make sure it's globally unique for
177 ## all running rhodecode instances. Leave empty if you don't use it
177 ## all running rhodecode instances. Leave empty if you don't use it
178 instance_id =
178 instance_id =
179
179
180 ## alternative return HTTP header for failed authentication. Default HTTP
180 ## alternative return HTTP header for failed authentication. Default HTTP
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
182 ## handling that. Set this variable to 403 to return HTTPForbidden
182 ## handling that. Set this variable to 403 to return HTTPForbidden
183 auth_ret_code =
183 auth_ret_code =
184
184
185 ## locking return code. When repository is locked return this HTTP code. 2XX
185 ## locking return code. When repository is locked return this HTTP code. 2XX
186 ## codes don't break the transactions while 4XX codes do
186 ## codes don't break the transactions while 4XX codes do
187 lock_ret_code = 423
187 lock_ret_code = 423
188
188
189
189
190 ####################################
190 ####################################
191 ### CELERY CONFIG ####
191 ### CELERY CONFIG ####
192 ####################################
192 ####################################
193 use_celery = false
193 use_celery = false
194 broker.host = localhost
194 broker.host = localhost
195 broker.vhost = rabbitmqhost
195 broker.vhost = rabbitmqhost
196 broker.port = 5672
196 broker.port = 5672
197 broker.user = rabbitmq
197 broker.user = rabbitmq
198 broker.password = qweqwe
198 broker.password = qweqwe
199
199
200 celery.imports = rhodecode.lib.celerylib.tasks
200 celery.imports = rhodecode.lib.celerylib.tasks
201
201
202 celery.result.backend = amqp
202 celery.result.backend = amqp
203 celery.result.dburi = amqp://
203 celery.result.dburi = amqp://
204 celery.result.serialier = json
204 celery.result.serialier = json
205
205
206 #celery.send.task.error.emails = true
206 #celery.send.task.error.emails = true
207 #celery.amqp.task.result.expires = 18000
207 #celery.amqp.task.result.expires = 18000
208
208
209 celeryd.concurrency = 2
209 celeryd.concurrency = 2
210 #celeryd.log.file = celeryd.log
210 #celeryd.log.file = celeryd.log
211 celeryd.log.level = debug
211 celeryd.log.level = debug
212 celeryd.max.tasks.per.child = 1
212 celeryd.max.tasks.per.child = 1
213
213
214 ## tasks will never be sent to the queue, but executed locally instead.
214 ## tasks will never be sent to the queue, but executed locally instead.
215 celery.always.eager = false
215 celery.always.eager = false
216
216
217 ####################################
217 ####################################
218 ### BEAKER CACHE ####
218 ### BEAKER CACHE ####
219 ####################################
219 ####################################
220 beaker.cache.data_dir=%(here)s/data/cache/data
220 beaker.cache.data_dir=%(here)s/data/cache/data
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
222
222
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
224
224
225 beaker.cache.super_short_term.type=memory
225 beaker.cache.super_short_term.type=memory
226 beaker.cache.super_short_term.expire=10
226 beaker.cache.super_short_term.expire=10
227 beaker.cache.super_short_term.key_length = 256
227 beaker.cache.super_short_term.key_length = 256
228
228
229 beaker.cache.short_term.type=memory
229 beaker.cache.short_term.type=memory
230 beaker.cache.short_term.expire=60
230 beaker.cache.short_term.expire=60
231 beaker.cache.short_term.key_length = 256
231 beaker.cache.short_term.key_length = 256
232
232
233 beaker.cache.long_term.type=memory
233 beaker.cache.long_term.type=memory
234 beaker.cache.long_term.expire=36000
234 beaker.cache.long_term.expire=36000
235 beaker.cache.long_term.key_length = 256
235 beaker.cache.long_term.key_length = 256
236
236
237 beaker.cache.sql_cache_short.type=memory
237 beaker.cache.sql_cache_short.type=memory
238 beaker.cache.sql_cache_short.expire=10
238 beaker.cache.sql_cache_short.expire=10
239 beaker.cache.sql_cache_short.key_length = 256
239 beaker.cache.sql_cache_short.key_length = 256
240
240
241 beaker.cache.sql_cache_med.type=memory
241 beaker.cache.sql_cache_med.type=memory
242 beaker.cache.sql_cache_med.expire=360
242 beaker.cache.sql_cache_med.expire=360
243 beaker.cache.sql_cache_med.key_length = 256
243 beaker.cache.sql_cache_med.key_length = 256
244
244
245 beaker.cache.sql_cache_long.type=file
245 beaker.cache.sql_cache_long.type=file
246 beaker.cache.sql_cache_long.expire=3600
246 beaker.cache.sql_cache_long.expire=3600
247 beaker.cache.sql_cache_long.key_length = 256
247 beaker.cache.sql_cache_long.key_length = 256
248
248
249 ####################################
249 ####################################
250 ### BEAKER SESSION ####
250 ### BEAKER SESSION ####
251 ####################################
251 ####################################
252 ## Type of storage used for the session, current types are
252 ## Type of storage used for the session, current types are
253 ## dbm, file, memcached, database, and memory.
253 ## dbm, file, memcached, database, and memory.
254 ## The storage uses the Container API
254 ## The storage uses the Container API
255 ## that is also used by the cache system.
255 ## that is also used by the cache system.
256
256
257 ## db session ##
257 ## db session ##
258 #beaker.session.type = ext:database
258 #beaker.session.type = ext:database
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
260 #beaker.session.table_name = db_session
260 #beaker.session.table_name = db_session
261
261
262 ## encrypted cookie client side session, good for many instances ##
262 ## encrypted cookie client side session, good for many instances ##
263 #beaker.session.type = cookie
263 #beaker.session.type = cookie
264
264
265 ## file based cookies (default) ##
265 ## file based cookies (default) ##
266 #beaker.session.type = file
266 #beaker.session.type = file
267
267
268
268
269 beaker.session.key = rhodecode
269 beaker.session.key = rhodecode
270 ## secure cookie requires AES python libraries
270 ## secure cookie requires AES python libraries
271 #beaker.session.encrypt_key = <key_for_encryption>
271 #beaker.session.encrypt_key = <key_for_encryption>
272 #beaker.session.validate_key = <validation_key>
272 #beaker.session.validate_key = <validation_key>
273
273
274 ## sets session as invalid if it haven't been accessed for given amount of time
274 ## sets session as invalid if it haven't been accessed for given amount of time
275 beaker.session.timeout = 2592000
275 beaker.session.timeout = 2592000
276 beaker.session.httponly = true
276 beaker.session.httponly = true
277 #beaker.session.cookie_path = /<your-prefix>
277 #beaker.session.cookie_path = /<your-prefix>
278
278
279 ## uncomment for https secure cookie
279 ## uncomment for https secure cookie
280 beaker.session.secure = false
280 beaker.session.secure = false
281
281
282 ## auto save the session to not to use .save()
282 ## auto save the session to not to use .save()
283 beaker.session.auto = False
283 beaker.session.auto = False
284
284
285 ## default cookie expiration time in seconds `true` expire at browser close ##
285 ## default cookie expiration time in seconds `true` expire at browser close ##
286 #beaker.session.cookie_expires = 3600
286 #beaker.session.cookie_expires = 3600
287
287
288
288
289 ############################
289 ############################
290 ## ERROR HANDLING SYSTEMS ##
290 ## ERROR HANDLING SYSTEMS ##
291 ############################
291 ############################
292
292
293 ####################
293 ####################
294 ### [errormator] ###
294 ### [errormator] ###
295 ####################
295 ####################
296
296
297 ## Errormator is tailored to work with RhodeCode, see
297 ## Errormator is tailored to work with RhodeCode, see
298 ## http://errormator.com for details how to obtain an account
298 ## http://errormator.com for details how to obtain an account
299 ## you must install python package `errormator_client` to make it work
299 ## you must install python package `errormator_client` to make it work
300
300
301 ## errormator enabled
301 ## errormator enabled
302 errormator = false
302 errormator = false
303
303
304 errormator.server_url = https://api.errormator.com
304 errormator.server_url = https://api.errormator.com
305 errormator.api_key = YOUR_API_KEY
305 errormator.api_key = YOUR_API_KEY
306
306
307 ## TWEAK AMOUNT OF INFO SENT HERE
307 ## TWEAK AMOUNT OF INFO SENT HERE
308
308
309 ## enables 404 error logging (default False)
309 ## enables 404 error logging (default False)
310 errormator.report_404 = false
310 errormator.report_404 = false
311
311
312 ## time in seconds after request is considered being slow (default 1)
312 ## time in seconds after request is considered being slow (default 1)
313 errormator.slow_request_time = 1
313 errormator.slow_request_time = 1
314
314
315 ## record slow requests in application
315 ## record slow requests in application
316 ## (needs to be enabled for slow datastore recording and time tracking)
316 ## (needs to be enabled for slow datastore recording and time tracking)
317 errormator.slow_requests = true
317 errormator.slow_requests = true
318
318
319 ## enable hooking to application loggers
319 ## enable hooking to application loggers
320 # errormator.logging = true
320 # errormator.logging = true
321
321
322 ## minimum log level for log capture
322 ## minimum log level for log capture
323 # errormator.logging.level = WARNING
323 # errormator.logging.level = WARNING
324
324
325 ## send logs only from erroneous/slow requests
325 ## send logs only from erroneous/slow requests
326 ## (saves API quota for intensive logging)
326 ## (saves API quota for intensive logging)
327 errormator.logging_on_error = false
327 errormator.logging_on_error = false
328
328
329 ## list of additonal keywords that should be grabbed from environ object
329 ## list of additonal keywords that should be grabbed from environ object
330 ## can be string with comma separated list of words in lowercase
330 ## can be string with comma separated list of words in lowercase
331 ## (by default client will always send following info:
331 ## (by default client will always send following info:
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
333 ## start with HTTP* this list be extended with additional keywords here
333 ## start with HTTP* this list be extended with additional keywords here
334 errormator.environ_keys_whitelist =
334 errormator.environ_keys_whitelist =
335
335
336
336
337 ## list of keywords that should be blanked from request object
337 ## list of keywords that should be blanked from request object
338 ## can be string with comma separated list of words in lowercase
338 ## can be string with comma separated list of words in lowercase
339 ## (by default client will always blank keys that contain following words
339 ## (by default client will always blank keys that contain following words
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
341 ## this list be extended with additional keywords set here
341 ## this list be extended with additional keywords set here
342 errormator.request_keys_blacklist =
342 errormator.request_keys_blacklist =
343
343
344
344
345 ## list of namespaces that should be ignores when gathering log entries
345 ## list of namespaces that should be ignores when gathering log entries
346 ## can be string with comma separated list of namespaces
346 ## can be string with comma separated list of namespaces
347 ## (by default the client ignores own entries: errormator_client.client)
347 ## (by default the client ignores own entries: errormator_client.client)
348 errormator.log_namespace_blacklist =
348 errormator.log_namespace_blacklist =
349
349
350
350
351 ################
351 ################
352 ### [sentry] ###
352 ### [sentry] ###
353 ################
353 ################
354
354
355 ## sentry is a alternative open source error aggregator
355 ## sentry is a alternative open source error aggregator
356 ## you must install python packages `sentry` and `raven` to enable
356 ## you must install python packages `sentry` and `raven` to enable
357
357
358 sentry.dsn = YOUR_DNS
358 sentry.dsn = YOUR_DNS
359 sentry.servers =
359 sentry.servers =
360 sentry.name =
360 sentry.name =
361 sentry.key =
361 sentry.key =
362 sentry.public_key =
362 sentry.public_key =
363 sentry.secret_key =
363 sentry.secret_key =
364 sentry.project =
364 sentry.project =
365 sentry.site =
365 sentry.site =
366 sentry.include_paths =
366 sentry.include_paths =
367 sentry.exclude_paths =
367 sentry.exclude_paths =
368
368
369
369
370 ################################################################################
370 ################################################################################
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
373 ## execute malicious code after an exception is raised. ##
373 ## execute malicious code after an exception is raised. ##
374 ################################################################################
374 ################################################################################
375 set debug = false
375 set debug = false
376
376
377 ##################################
377 ##################################
378 ### LOGVIEW CONFIG ###
378 ### LOGVIEW CONFIG ###
379 ##################################
379 ##################################
380 logview.sqlalchemy = #faa
380 logview.sqlalchemy = #faa
381 logview.pylons.templating = #bfb
381 logview.pylons.templating = #bfb
382 logview.pylons.util = #eee
382 logview.pylons.util = #eee
383
383
384 #########################################################
384 #########################################################
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
386 #########################################################
386 #########################################################
387 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
387 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
388 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
388 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
389 sqlalchemy.db1.echo = false
389 sqlalchemy.db1.echo = false
390 sqlalchemy.db1.pool_recycle = 3600
390 sqlalchemy.db1.pool_recycle = 3600
391 sqlalchemy.db1.convert_unicode = true
391 sqlalchemy.db1.convert_unicode = true
392
392
393 ################################
393 ################################
394 ### LOGGING CONFIGURATION ####
394 ### LOGGING CONFIGURATION ####
395 ################################
395 ################################
396 [loggers]
396 [loggers]
397 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
397 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
398
398
399 [handlers]
399 [handlers]
400 keys = console, console_sql
400 keys = console, console_sql
401
401
402 [formatters]
402 [formatters]
403 keys = generic, color_formatter, color_formatter_sql
403 keys = generic, color_formatter, color_formatter_sql
404
404
405 #############
405 #############
406 ## LOGGERS ##
406 ## LOGGERS ##
407 #############
407 #############
408 [logger_root]
408 [logger_root]
409 level = NOTSET
409 level = NOTSET
410 handlers = console
410 handlers = console
411
411
412 [logger_routes]
412 [logger_routes]
413 level = DEBUG
413 level = DEBUG
414 handlers =
414 handlers =
415 qualname = routes.middleware
415 qualname = routes.middleware
416 ## "level = DEBUG" logs the route matched and routing variables.
416 ## "level = DEBUG" logs the route matched and routing variables.
417 propagate = 1
417 propagate = 1
418
418
419 [logger_beaker]
419 [logger_beaker]
420 level = DEBUG
420 level = DEBUG
421 handlers =
421 handlers =
422 qualname = beaker.container
422 qualname = beaker.container
423 propagate = 1
423 propagate = 1
424
424
425 [logger_templates]
425 [logger_templates]
426 level = INFO
426 level = INFO
427 handlers =
427 handlers =
428 qualname = pylons.templating
428 qualname = pylons.templating
429 propagate = 1
429 propagate = 1
430
430
431 [logger_rhodecode]
431 [logger_rhodecode]
432 level = DEBUG
432 level = DEBUG
433 handlers =
433 handlers =
434 qualname = rhodecode
434 qualname = rhodecode
435 propagate = 1
435 propagate = 1
436
436
437 [logger_sqlalchemy]
437 [logger_sqlalchemy]
438 level = INFO
438 level = INFO
439 handlers = console_sql
439 handlers = console_sql
440 qualname = sqlalchemy.engine
440 qualname = sqlalchemy.engine
441 propagate = 0
441 propagate = 0
442
442
443 [logger_whoosh_indexer]
443 [logger_whoosh_indexer]
444 level = DEBUG
444 level = DEBUG
445 handlers =
445 handlers =
446 qualname = whoosh_indexer
446 qualname = whoosh_indexer
447 propagate = 1
447 propagate = 1
448
448
449 ##############
449 ##############
450 ## HANDLERS ##
450 ## HANDLERS ##
451 ##############
451 ##############
452
452
453 [handler_console]
453 [handler_console]
454 class = StreamHandler
454 class = StreamHandler
455 args = (sys.stderr,)
455 args = (sys.stderr,)
456 level = INFO
456 level = INFO
457 formatter = generic
457 formatter = generic
458
458
459 [handler_console_sql]
459 [handler_console_sql]
460 class = StreamHandler
460 class = StreamHandler
461 args = (sys.stderr,)
461 args = (sys.stderr,)
462 level = WARN
462 level = WARN
463 formatter = generic
463 formatter = generic
464
464
465 ################
465 ################
466 ## FORMATTERS ##
466 ## FORMATTERS ##
467 ################
467 ################
468
468
469 [formatter_generic]
469 [formatter_generic]
470 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
470 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
471 datefmt = %Y-%m-%d %H:%M:%S
471 datefmt = %Y-%m-%d %H:%M:%S
472
472
473 [formatter_color_formatter]
473 [formatter_color_formatter]
474 class=rhodecode.lib.colored_formatter.ColorFormatter
474 class=rhodecode.lib.colored_formatter.ColorFormatter
475 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
475 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
476 datefmt = %Y-%m-%d %H:%M:%S
476 datefmt = %Y-%m-%d %H:%M:%S
477
477
478 [formatter_color_formatter_sql]
478 [formatter_color_formatter_sql]
479 class=rhodecode.lib.colored_formatter.ColorFormatterSql
479 class=rhodecode.lib.colored_formatter.ColorFormatterSql
480 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
480 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
481 datefmt = %Y-%m-%d %H:%M:%S
481 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,491 +1,491 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE
32 ## PASTE
33 ## nr of threads to spawn
33 ## nr of threads to spawn
34 #threadpool_workers = 5
34 #threadpool_workers = 5
35
35
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38
38
39 ## option to use threads of process
39 ## option to use threads of process
40 #use_threadpool = true
40 #use_threadpool = true
41
41
42 #use = egg:Paste#http
42 #use = egg:Paste#http
43
43
44 ## WAITRESS
44 ## WAITRESS
45 threads = 5
45 threads = 5
46 ## 100GB
46 ## 100GB
47 max_request_body_size = 107374182400
47 max_request_body_size = 107374182400
48 use = egg:waitress#main
48 use = egg:waitress#main
49
49
50 host = 127.0.0.1
50 host = 127.0.0.1
51 port = 5000
51 port = 5000
52
52
53 ## prefix middleware for rc
53 ## prefix middleware for rc
54 #[filter:proxy-prefix]
54 #[filter:proxy-prefix]
55 #use = egg:PasteDeploy#prefix
55 #use = egg:PasteDeploy#prefix
56 #prefix = /<your-prefix>
56 #prefix = /<your-prefix>
57
57
58 [app:main]
58 [app:main]
59 use = egg:rhodecode
59 use = egg:rhodecode
60 ## enable proxy prefix middleware
60 ## enable proxy prefix middleware
61 #filter-with = proxy-prefix
61 #filter-with = proxy-prefix
62
62
63 full_stack = true
63 full_stack = true
64 static_files = true
64 static_files = true
65 ## Optional Languages
65 ## Optional Languages
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
67 lang = en
67 lang = en
68 cache_dir = %(here)s/data
68 cache_dir = %(here)s/data
69 index_dir = %(here)s/data/index
69 index_dir = %(here)s/data/index
70
70
71 ## uncomment and set this path to use archive download cache
71 ## uncomment and set this path to use archive download cache
72 #archive_cache_dir = /tmp/tarballcache
72 #archive_cache_dir = /tmp/tarballcache
73
73
74 ## change this to unique ID for security
74 ## change this to unique ID for security
75 app_instance_uuid = ${app_instance_uuid}
75 app_instance_uuid = ${app_instance_uuid}
76
76
77 ## cut off limit for large diffs (size in bytes)
77 ## cut off limit for large diffs (size in bytes)
78 cut_off_limit = 256000
78 cut_off_limit = 256000
79
79
80 ## use cache version of scm repo everywhere
80 ## use cache version of scm repo everywhere
81 vcs_full_cache = true
81 vcs_full_cache = true
82
82
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
84 force_https = false
84 force_https = false
85
85
86 ## use Strict-Transport-Security headers
86 ## use Strict-Transport-Security headers
87 use_htsts = false
87 use_htsts = false
88
88
89 ## number of commits stats will parse on each iteration
89 ## number of commits stats will parse on each iteration
90 commit_parse_limit = 25
90 commit_parse_limit = 25
91
91
92 ## number of items displayed in lightweight dashboard before paginating is shown
92 ## number of items displayed in lightweight dashboard before paginating is shown
93 dashboard_items = 100
93 dashboard_items = 100
94
94
95 ## use gravatar service to display avatars
95 ## use gravatar service to display avatars
96 use_gravatar = true
96 use_gravatar = true
97
97
98 ## path to git executable
98 ## path to git executable
99 git_path = git
99 git_path = git
100
100
101 ## git rev filter option, --all is the default filter, if you need to
101 ## git rev filter option, --all is the default filter, if you need to
102 ## hide all refs in changelog switch this to --branches --tags
102 ## hide all refs in changelog switch this to --branches --tags
103 git_rev_filter=--all
103 git_rev_filter=--all
104
104
105 ## RSS feed options
105 ## RSS feed options
106 rss_cut_off_limit = 256000
106 rss_cut_off_limit = 256000
107 rss_items_per_page = 10
107 rss_items_per_page = 10
108 rss_include_diff = false
108 rss_include_diff = false
109
109
110 ## show hash options for changelog
110 ## options for showing and identifying changesets
111 sha_len = 12
111 show_sha_length = 12
112 sha_show_numeric_rev = true
112 show_revision_number = true
113
113
114
114
115 ## alternative_gravatar_url allows you to use your own avatar server application
115 ## alternative_gravatar_url allows you to use your own avatar server application
116 ## the following parts of the URL will be replaced
116 ## the following parts of the URL will be replaced
117 ## {email} user email
117 ## {email} user email
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
119 ## {size} size of the image that is expected from the server application
119 ## {size} size of the image that is expected from the server application
120 ## {scheme} http/https from RhodeCode server
120 ## {scheme} http/https from RhodeCode server
121 ## {netloc} network location from RhodeCode server
121 ## {netloc} network location from RhodeCode server
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
124
124
125
125
126 ## container auth options
126 ## container auth options
127 container_auth_enabled = false
127 container_auth_enabled = false
128 proxypass_auth_enabled = false
128 proxypass_auth_enabled = false
129
129
130 ## default encoding used to convert from and to unicode
130 ## default encoding used to convert from and to unicode
131 ## can be also a comma seperated list of encoding in case of mixed encodings
131 ## can be also a comma seperated list of encoding in case of mixed encodings
132 default_encoding = utf8
132 default_encoding = utf8
133
133
134 ## overwrite schema of clone url
134 ## overwrite schema of clone url
135 ## available vars:
135 ## available vars:
136 ## scheme - http/https
136 ## scheme - http/https
137 ## user - current user
137 ## user - current user
138 ## pass - password
138 ## pass - password
139 ## netloc - network location
139 ## netloc - network location
140 ## path - usually repo_name
140 ## path - usually repo_name
141
141
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
143
143
144 ## issue tracking mapping for commits messages
144 ## issue tracking mapping for commits messages
145 ## comment out issue_pat, issue_server, issue_prefix to enable
145 ## comment out issue_pat, issue_server, issue_prefix to enable
146
146
147 ## pattern to get the issues from commit messages
147 ## pattern to get the issues from commit messages
148 ## default one used here is #<numbers> with a regex passive group for `#`
148 ## default one used here is #<numbers> with a regex passive group for `#`
149 ## {id} will be all groups matched from this pattern
149 ## {id} will be all groups matched from this pattern
150
150
151 issue_pat = (?:\s*#)(\d+)
151 issue_pat = (?:\s*#)(\d+)
152
152
153 ## server url to the issue, each {id} will be replaced with match
153 ## server url to the issue, each {id} will be replaced with match
154 ## fetched from the regex and {repo} is replaced with full repository name
154 ## fetched from the regex and {repo} is replaced with full repository name
155 ## including groups {repo_name} is replaced with just name of repo
155 ## including groups {repo_name} is replaced with just name of repo
156
156
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
158
158
159 ## prefix to add to link to indicate it's an url
159 ## prefix to add to link to indicate it's an url
160 ## #314 will be replaced by <issue_prefix><id>
160 ## #314 will be replaced by <issue_prefix><id>
161
161
162 issue_prefix = #
162 issue_prefix = #
163
163
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
165 ## multiple patterns, to other issues server, wiki or others
165 ## multiple patterns, to other issues server, wiki or others
166 ## below an example how to create a wiki pattern
166 ## below an example how to create a wiki pattern
167 # #wiki-some-id -> https://mywiki.com/some-id
167 # #wiki-some-id -> https://mywiki.com/some-id
168
168
169 #issue_pat_wiki = (?:wiki-)(.+)
169 #issue_pat_wiki = (?:wiki-)(.+)
170 #issue_server_link_wiki = https://mywiki.com/{id}
170 #issue_server_link_wiki = https://mywiki.com/{id}
171 #issue_prefix_wiki = WIKI-
171 #issue_prefix_wiki = WIKI-
172
172
173
173
174 ## instance-id prefix
174 ## instance-id prefix
175 ## a prefix key for this instance used for cache invalidation when running
175 ## a prefix key for this instance used for cache invalidation when running
176 ## multiple instances of rhodecode, make sure it's globally unique for
176 ## multiple instances of rhodecode, make sure it's globally unique for
177 ## all running rhodecode instances. Leave empty if you don't use it
177 ## all running rhodecode instances. Leave empty if you don't use it
178 instance_id =
178 instance_id =
179
179
180 ## alternative return HTTP header for failed authentication. Default HTTP
180 ## alternative return HTTP header for failed authentication. Default HTTP
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
182 ## handling that. Set this variable to 403 to return HTTPForbidden
182 ## handling that. Set this variable to 403 to return HTTPForbidden
183 auth_ret_code =
183 auth_ret_code =
184
184
185 ## locking return code. When repository is locked return this HTTP code. 2XX
185 ## locking return code. When repository is locked return this HTTP code. 2XX
186 ## codes don't break the transactions while 4XX codes do
186 ## codes don't break the transactions while 4XX codes do
187 lock_ret_code = 423
187 lock_ret_code = 423
188
188
189
189
190 ####################################
190 ####################################
191 ### CELERY CONFIG ####
191 ### CELERY CONFIG ####
192 ####################################
192 ####################################
193 use_celery = false
193 use_celery = false
194 broker.host = localhost
194 broker.host = localhost
195 broker.vhost = rabbitmqhost
195 broker.vhost = rabbitmqhost
196 broker.port = 5672
196 broker.port = 5672
197 broker.user = rabbitmq
197 broker.user = rabbitmq
198 broker.password = qweqwe
198 broker.password = qweqwe
199
199
200 celery.imports = rhodecode.lib.celerylib.tasks
200 celery.imports = rhodecode.lib.celerylib.tasks
201
201
202 celery.result.backend = amqp
202 celery.result.backend = amqp
203 celery.result.dburi = amqp://
203 celery.result.dburi = amqp://
204 celery.result.serialier = json
204 celery.result.serialier = json
205
205
206 #celery.send.task.error.emails = true
206 #celery.send.task.error.emails = true
207 #celery.amqp.task.result.expires = 18000
207 #celery.amqp.task.result.expires = 18000
208
208
209 celeryd.concurrency = 2
209 celeryd.concurrency = 2
210 #celeryd.log.file = celeryd.log
210 #celeryd.log.file = celeryd.log
211 celeryd.log.level = debug
211 celeryd.log.level = debug
212 celeryd.max.tasks.per.child = 1
212 celeryd.max.tasks.per.child = 1
213
213
214 ## tasks will never be sent to the queue, but executed locally instead.
214 ## tasks will never be sent to the queue, but executed locally instead.
215 celery.always.eager = false
215 celery.always.eager = false
216
216
217 ####################################
217 ####################################
218 ### BEAKER CACHE ####
218 ### BEAKER CACHE ####
219 ####################################
219 ####################################
220 beaker.cache.data_dir=%(here)s/data/cache/data
220 beaker.cache.data_dir=%(here)s/data/cache/data
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
221 beaker.cache.lock_dir=%(here)s/data/cache/lock
222
222
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
224
224
225 beaker.cache.super_short_term.type=memory
225 beaker.cache.super_short_term.type=memory
226 beaker.cache.super_short_term.expire=10
226 beaker.cache.super_short_term.expire=10
227 beaker.cache.super_short_term.key_length = 256
227 beaker.cache.super_short_term.key_length = 256
228
228
229 beaker.cache.short_term.type=memory
229 beaker.cache.short_term.type=memory
230 beaker.cache.short_term.expire=60
230 beaker.cache.short_term.expire=60
231 beaker.cache.short_term.key_length = 256
231 beaker.cache.short_term.key_length = 256
232
232
233 beaker.cache.long_term.type=memory
233 beaker.cache.long_term.type=memory
234 beaker.cache.long_term.expire=36000
234 beaker.cache.long_term.expire=36000
235 beaker.cache.long_term.key_length = 256
235 beaker.cache.long_term.key_length = 256
236
236
237 beaker.cache.sql_cache_short.type=memory
237 beaker.cache.sql_cache_short.type=memory
238 beaker.cache.sql_cache_short.expire=10
238 beaker.cache.sql_cache_short.expire=10
239 beaker.cache.sql_cache_short.key_length = 256
239 beaker.cache.sql_cache_short.key_length = 256
240
240
241 beaker.cache.sql_cache_med.type=memory
241 beaker.cache.sql_cache_med.type=memory
242 beaker.cache.sql_cache_med.expire=360
242 beaker.cache.sql_cache_med.expire=360
243 beaker.cache.sql_cache_med.key_length = 256
243 beaker.cache.sql_cache_med.key_length = 256
244
244
245 beaker.cache.sql_cache_long.type=file
245 beaker.cache.sql_cache_long.type=file
246 beaker.cache.sql_cache_long.expire=3600
246 beaker.cache.sql_cache_long.expire=3600
247 beaker.cache.sql_cache_long.key_length = 256
247 beaker.cache.sql_cache_long.key_length = 256
248
248
249 ####################################
249 ####################################
250 ### BEAKER SESSION ####
250 ### BEAKER SESSION ####
251 ####################################
251 ####################################
252 ## Type of storage used for the session, current types are
252 ## Type of storage used for the session, current types are
253 ## dbm, file, memcached, database, and memory.
253 ## dbm, file, memcached, database, and memory.
254 ## The storage uses the Container API
254 ## The storage uses the Container API
255 ## that is also used by the cache system.
255 ## that is also used by the cache system.
256
256
257 ## db session ##
257 ## db session ##
258 #beaker.session.type = ext:database
258 #beaker.session.type = ext:database
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
260 #beaker.session.table_name = db_session
260 #beaker.session.table_name = db_session
261
261
262 ## encrypted cookie client side session, good for many instances ##
262 ## encrypted cookie client side session, good for many instances ##
263 #beaker.session.type = cookie
263 #beaker.session.type = cookie
264
264
265 ## file based cookies (default) ##
265 ## file based cookies (default) ##
266 #beaker.session.type = file
266 #beaker.session.type = file
267
267
268
268
269 beaker.session.key = rhodecode
269 beaker.session.key = rhodecode
270 ## secure cookie requires AES python libraries
270 ## secure cookie requires AES python libraries
271 #beaker.session.encrypt_key = <key_for_encryption>
271 #beaker.session.encrypt_key = <key_for_encryption>
272 #beaker.session.validate_key = <validation_key>
272 #beaker.session.validate_key = <validation_key>
273
273
274 ## sets session as invalid if it haven't been accessed for given amount of time
274 ## sets session as invalid if it haven't been accessed for given amount of time
275 beaker.session.timeout = 2592000
275 beaker.session.timeout = 2592000
276 beaker.session.httponly = true
276 beaker.session.httponly = true
277 #beaker.session.cookie_path = /<your-prefix>
277 #beaker.session.cookie_path = /<your-prefix>
278
278
279 ## uncomment for https secure cookie
279 ## uncomment for https secure cookie
280 beaker.session.secure = false
280 beaker.session.secure = false
281
281
282 ## auto save the session to not to use .save()
282 ## auto save the session to not to use .save()
283 beaker.session.auto = False
283 beaker.session.auto = False
284
284
285 ## default cookie expiration time in seconds `true` expire at browser close ##
285 ## default cookie expiration time in seconds `true` expire at browser close ##
286 #beaker.session.cookie_expires = 3600
286 #beaker.session.cookie_expires = 3600
287
287
288
288
289 ############################
289 ############################
290 ## ERROR HANDLING SYSTEMS ##
290 ## ERROR HANDLING SYSTEMS ##
291 ############################
291 ############################
292
292
293 ####################
293 ####################
294 ### [errormator] ###
294 ### [errormator] ###
295 ####################
295 ####################
296
296
297 ## Errormator is tailored to work with RhodeCode, see
297 ## Errormator is tailored to work with RhodeCode, see
298 ## http://errormator.com for details how to obtain an account
298 ## http://errormator.com for details how to obtain an account
299 ## you must install python package `errormator_client` to make it work
299 ## you must install python package `errormator_client` to make it work
300
300
301 ## errormator enabled
301 ## errormator enabled
302 errormator = false
302 errormator = false
303
303
304 errormator.server_url = https://api.errormator.com
304 errormator.server_url = https://api.errormator.com
305 errormator.api_key = YOUR_API_KEY
305 errormator.api_key = YOUR_API_KEY
306
306
307 ## TWEAK AMOUNT OF INFO SENT HERE
307 ## TWEAK AMOUNT OF INFO SENT HERE
308
308
309 ## enables 404 error logging (default False)
309 ## enables 404 error logging (default False)
310 errormator.report_404 = false
310 errormator.report_404 = false
311
311
312 ## time in seconds after request is considered being slow (default 1)
312 ## time in seconds after request is considered being slow (default 1)
313 errormator.slow_request_time = 1
313 errormator.slow_request_time = 1
314
314
315 ## record slow requests in application
315 ## record slow requests in application
316 ## (needs to be enabled for slow datastore recording and time tracking)
316 ## (needs to be enabled for slow datastore recording and time tracking)
317 errormator.slow_requests = true
317 errormator.slow_requests = true
318
318
319 ## enable hooking to application loggers
319 ## enable hooking to application loggers
320 # errormator.logging = true
320 # errormator.logging = true
321
321
322 ## minimum log level for log capture
322 ## minimum log level for log capture
323 # errormator.logging.level = WARNING
323 # errormator.logging.level = WARNING
324
324
325 ## send logs only from erroneous/slow requests
325 ## send logs only from erroneous/slow requests
326 ## (saves API quota for intensive logging)
326 ## (saves API quota for intensive logging)
327 errormator.logging_on_error = false
327 errormator.logging_on_error = false
328
328
329 ## list of additonal keywords that should be grabbed from environ object
329 ## list of additonal keywords that should be grabbed from environ object
330 ## can be string with comma separated list of words in lowercase
330 ## can be string with comma separated list of words in lowercase
331 ## (by default client will always send following info:
331 ## (by default client will always send following info:
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
333 ## start with HTTP* this list be extended with additional keywords here
333 ## start with HTTP* this list be extended with additional keywords here
334 errormator.environ_keys_whitelist =
334 errormator.environ_keys_whitelist =
335
335
336
336
337 ## list of keywords that should be blanked from request object
337 ## list of keywords that should be blanked from request object
338 ## can be string with comma separated list of words in lowercase
338 ## can be string with comma separated list of words in lowercase
339 ## (by default client will always blank keys that contain following words
339 ## (by default client will always blank keys that contain following words
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
341 ## this list be extended with additional keywords set here
341 ## this list be extended with additional keywords set here
342 errormator.request_keys_blacklist =
342 errormator.request_keys_blacklist =
343
343
344
344
345 ## list of namespaces that should be ignores when gathering log entries
345 ## list of namespaces that should be ignores when gathering log entries
346 ## can be string with comma separated list of namespaces
346 ## can be string with comma separated list of namespaces
347 ## (by default the client ignores own entries: errormator_client.client)
347 ## (by default the client ignores own entries: errormator_client.client)
348 errormator.log_namespace_blacklist =
348 errormator.log_namespace_blacklist =
349
349
350
350
351 ################
351 ################
352 ### [sentry] ###
352 ### [sentry] ###
353 ################
353 ################
354
354
355 ## sentry is a alternative open source error aggregator
355 ## sentry is a alternative open source error aggregator
356 ## you must install python packages `sentry` and `raven` to enable
356 ## you must install python packages `sentry` and `raven` to enable
357
357
358 sentry.dsn = YOUR_DNS
358 sentry.dsn = YOUR_DNS
359 sentry.servers =
359 sentry.servers =
360 sentry.name =
360 sentry.name =
361 sentry.key =
361 sentry.key =
362 sentry.public_key =
362 sentry.public_key =
363 sentry.secret_key =
363 sentry.secret_key =
364 sentry.project =
364 sentry.project =
365 sentry.site =
365 sentry.site =
366 sentry.include_paths =
366 sentry.include_paths =
367 sentry.exclude_paths =
367 sentry.exclude_paths =
368
368
369
369
370 ################################################################################
370 ################################################################################
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
373 ## execute malicious code after an exception is raised. ##
373 ## execute malicious code after an exception is raised. ##
374 ################################################################################
374 ################################################################################
375 set debug = false
375 set debug = false
376
376
377 ##################################
377 ##################################
378 ### LOGVIEW CONFIG ###
378 ### LOGVIEW CONFIG ###
379 ##################################
379 ##################################
380 logview.sqlalchemy = #faa
380 logview.sqlalchemy = #faa
381 logview.pylons.templating = #bfb
381 logview.pylons.templating = #bfb
382 logview.pylons.util = #eee
382 logview.pylons.util = #eee
383
383
384 #########################################################
384 #########################################################
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
386 #########################################################
386 #########################################################
387
387
388 # SQLITE [default]
388 # SQLITE [default]
389 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
389 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
390
390
391 # POSTGRESQL
391 # POSTGRESQL
392 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
392 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
393
393
394 # MySQL
394 # MySQL
395 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
395 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
396
396
397 # see sqlalchemy docs for others
397 # see sqlalchemy docs for others
398
398
399 sqlalchemy.db1.echo = false
399 sqlalchemy.db1.echo = false
400 sqlalchemy.db1.pool_recycle = 3600
400 sqlalchemy.db1.pool_recycle = 3600
401 sqlalchemy.db1.convert_unicode = true
401 sqlalchemy.db1.convert_unicode = true
402
402
403 ################################
403 ################################
404 ### LOGGING CONFIGURATION ####
404 ### LOGGING CONFIGURATION ####
405 ################################
405 ################################
406 [loggers]
406 [loggers]
407 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
407 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
408
408
409 [handlers]
409 [handlers]
410 keys = console, console_sql
410 keys = console, console_sql
411
411
412 [formatters]
412 [formatters]
413 keys = generic, color_formatter, color_formatter_sql
413 keys = generic, color_formatter, color_formatter_sql
414
414
415 #############
415 #############
416 ## LOGGERS ##
416 ## LOGGERS ##
417 #############
417 #############
418 [logger_root]
418 [logger_root]
419 level = NOTSET
419 level = NOTSET
420 handlers = console
420 handlers = console
421
421
422 [logger_routes]
422 [logger_routes]
423 level = DEBUG
423 level = DEBUG
424 handlers =
424 handlers =
425 qualname = routes.middleware
425 qualname = routes.middleware
426 ## "level = DEBUG" logs the route matched and routing variables.
426 ## "level = DEBUG" logs the route matched and routing variables.
427 propagate = 1
427 propagate = 1
428
428
429 [logger_beaker]
429 [logger_beaker]
430 level = DEBUG
430 level = DEBUG
431 handlers =
431 handlers =
432 qualname = beaker.container
432 qualname = beaker.container
433 propagate = 1
433 propagate = 1
434
434
435 [logger_templates]
435 [logger_templates]
436 level = INFO
436 level = INFO
437 handlers =
437 handlers =
438 qualname = pylons.templating
438 qualname = pylons.templating
439 propagate = 1
439 propagate = 1
440
440
441 [logger_rhodecode]
441 [logger_rhodecode]
442 level = DEBUG
442 level = DEBUG
443 handlers =
443 handlers =
444 qualname = rhodecode
444 qualname = rhodecode
445 propagate = 1
445 propagate = 1
446
446
447 [logger_sqlalchemy]
447 [logger_sqlalchemy]
448 level = INFO
448 level = INFO
449 handlers = console_sql
449 handlers = console_sql
450 qualname = sqlalchemy.engine
450 qualname = sqlalchemy.engine
451 propagate = 0
451 propagate = 0
452
452
453 [logger_whoosh_indexer]
453 [logger_whoosh_indexer]
454 level = DEBUG
454 level = DEBUG
455 handlers =
455 handlers =
456 qualname = whoosh_indexer
456 qualname = whoosh_indexer
457 propagate = 1
457 propagate = 1
458
458
459 ##############
459 ##############
460 ## HANDLERS ##
460 ## HANDLERS ##
461 ##############
461 ##############
462
462
463 [handler_console]
463 [handler_console]
464 class = StreamHandler
464 class = StreamHandler
465 args = (sys.stderr,)
465 args = (sys.stderr,)
466 level = INFO
466 level = INFO
467 formatter = generic
467 formatter = generic
468
468
469 [handler_console_sql]
469 [handler_console_sql]
470 class = StreamHandler
470 class = StreamHandler
471 args = (sys.stderr,)
471 args = (sys.stderr,)
472 level = WARN
472 level = WARN
473 formatter = generic
473 formatter = generic
474
474
475 ################
475 ################
476 ## FORMATTERS ##
476 ## FORMATTERS ##
477 ################
477 ################
478
478
479 [formatter_generic]
479 [formatter_generic]
480 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
480 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
481 datefmt = %Y-%m-%d %H:%M:%S
481 datefmt = %Y-%m-%d %H:%M:%S
482
482
483 [formatter_color_formatter]
483 [formatter_color_formatter]
484 class=rhodecode.lib.colored_formatter.ColorFormatter
484 class=rhodecode.lib.colored_formatter.ColorFormatter
485 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
485 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
486 datefmt = %Y-%m-%d %H:%M:%S
486 datefmt = %Y-%m-%d %H:%M:%S
487
487
488 [formatter_color_formatter_sql]
488 [formatter_color_formatter_sql]
489 class=rhodecode.lib.colored_formatter.ColorFormatterSql
489 class=rhodecode.lib.colored_formatter.ColorFormatterSql
490 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
490 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
491 datefmt = %Y-%m-%d %H:%M:%S
491 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,1207 +1,1207 b''
1 """Helper functions
1 """Helper functions
2
2
3 Consists of functions to typically be used within templates, but also
3 Consists of functions to typically be used within templates, but also
4 available to Controllers. This module is available to both as 'h'.
4 available to Controllers. This module is available to both as 'h'.
5 """
5 """
6 import random
6 import random
7 import hashlib
7 import hashlib
8 import StringIO
8 import StringIO
9 import urllib
9 import urllib
10 import math
10 import math
11 import logging
11 import logging
12 import re
12 import re
13 import urlparse
13 import urlparse
14 import textwrap
14 import textwrap
15
15
16 from datetime import datetime
16 from datetime import datetime
17 from pygments.formatters.html import HtmlFormatter
17 from pygments.formatters.html import HtmlFormatter
18 from pygments import highlight as code_highlight
18 from pygments import highlight as code_highlight
19 from pylons import url, request, config
19 from pylons import url, request, config
20 from pylons.i18n.translation import _, ungettext
20 from pylons.i18n.translation import _, ungettext
21 from hashlib import md5
21 from hashlib import md5
22
22
23 from webhelpers.html import literal, HTML, escape
23 from webhelpers.html import literal, HTML, escape
24 from webhelpers.html.tools import *
24 from webhelpers.html.tools import *
25 from webhelpers.html.builder import make_tag
25 from webhelpers.html.builder import make_tag
26 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
26 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
27 end_form, file, form, hidden, image, javascript_link, link_to, \
27 end_form, file, form, hidden, image, javascript_link, link_to, \
28 link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
28 link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \
29 submit, text, password, textarea, title, ul, xml_declaration, radio
29 submit, text, password, textarea, title, ul, xml_declaration, radio
30 from webhelpers.html.tools import auto_link, button_to, highlight, \
30 from webhelpers.html.tools import auto_link, button_to, highlight, \
31 js_obfuscate, mail_to, strip_links, strip_tags, tag_re
31 js_obfuscate, mail_to, strip_links, strip_tags, tag_re
32 from webhelpers.number import format_byte_size, format_bit_size
32 from webhelpers.number import format_byte_size, format_bit_size
33 from webhelpers.pylonslib import Flash as _Flash
33 from webhelpers.pylonslib import Flash as _Flash
34 from webhelpers.pylonslib.secure_form import secure_form
34 from webhelpers.pylonslib.secure_form import secure_form
35 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
35 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
36 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
36 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
37 replace_whitespace, urlify, truncate, wrap_paragraphs
37 replace_whitespace, urlify, truncate, wrap_paragraphs
38 from webhelpers.date import time_ago_in_words
38 from webhelpers.date import time_ago_in_words
39 from webhelpers.paginate import Page
39 from webhelpers.paginate import Page
40 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
40 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
41 convert_boolean_attrs, NotGiven, _make_safe_id_component
41 convert_boolean_attrs, NotGiven, _make_safe_id_component
42
42
43 from rhodecode.lib.annotate import annotate_highlight
43 from rhodecode.lib.annotate import annotate_highlight
44 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
44 from rhodecode.lib.utils import repo_name_slug, get_custom_lexer
45 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
45 from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \
46 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\
46 get_changeset_safe, datetime_to_time, time_to_datetime, AttributeDict,\
47 safe_int
47 safe_int
48 from rhodecode.lib.markup_renderer import MarkupRenderer
48 from rhodecode.lib.markup_renderer import MarkupRenderer
49 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
49 from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
50 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
50 from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyChangeset
51 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
51 from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT
52 from rhodecode.model.changeset_status import ChangesetStatusModel
52 from rhodecode.model.changeset_status import ChangesetStatusModel
53 from rhodecode.model.db import URL_SEP, Permission
53 from rhodecode.model.db import URL_SEP, Permission
54
54
55 log = logging.getLogger(__name__)
55 log = logging.getLogger(__name__)
56
56
57
57
58 html_escape_table = {
58 html_escape_table = {
59 "&": "&amp;",
59 "&": "&amp;",
60 '"': "&quot;",
60 '"': "&quot;",
61 "'": "&apos;",
61 "'": "&apos;",
62 ">": "&gt;",
62 ">": "&gt;",
63 "<": "&lt;",
63 "<": "&lt;",
64 }
64 }
65
65
66
66
67 def html_escape(text):
67 def html_escape(text):
68 """Produce entities within text."""
68 """Produce entities within text."""
69 return "".join(html_escape_table.get(c, c) for c in text)
69 return "".join(html_escape_table.get(c, c) for c in text)
70
70
71
71
72 def shorter(text, size=20):
72 def shorter(text, size=20):
73 postfix = '...'
73 postfix = '...'
74 if len(text) > size:
74 if len(text) > size:
75 return text[:size - len(postfix)] + postfix
75 return text[:size - len(postfix)] + postfix
76 return text
76 return text
77
77
78
78
79 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
79 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
80 """
80 """
81 Reset button
81 Reset button
82 """
82 """
83 _set_input_attrs(attrs, type, name, value)
83 _set_input_attrs(attrs, type, name, value)
84 _set_id_attr(attrs, id, name)
84 _set_id_attr(attrs, id, name)
85 convert_boolean_attrs(attrs, ["disabled"])
85 convert_boolean_attrs(attrs, ["disabled"])
86 return HTML.input(**attrs)
86 return HTML.input(**attrs)
87
87
88 reset = _reset
88 reset = _reset
89 safeid = _make_safe_id_component
89 safeid = _make_safe_id_component
90
90
91
91
92 def FID(raw_id, path):
92 def FID(raw_id, path):
93 """
93 """
94 Creates a uniqe ID for filenode based on it's hash of path and revision
94 Creates a uniqe ID for filenode based on it's hash of path and revision
95 it's safe to use in urls
95 it's safe to use in urls
96
96
97 :param raw_id:
97 :param raw_id:
98 :param path:
98 :param path:
99 """
99 """
100
100
101 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
101 return 'C-%s-%s' % (short_id(raw_id), md5(safe_str(path)).hexdigest()[:12])
102
102
103
103
104 def get_token():
104 def get_token():
105 """Return the current authentication token, creating one if one doesn't
105 """Return the current authentication token, creating one if one doesn't
106 already exist.
106 already exist.
107 """
107 """
108 token_key = "_authentication_token"
108 token_key = "_authentication_token"
109 from pylons import session
109 from pylons import session
110 if not token_key in session:
110 if not token_key in session:
111 try:
111 try:
112 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
112 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
113 except AttributeError: # Python < 2.4
113 except AttributeError: # Python < 2.4
114 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
114 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
115 session[token_key] = token
115 session[token_key] = token
116 if hasattr(session, 'save'):
116 if hasattr(session, 'save'):
117 session.save()
117 session.save()
118 return session[token_key]
118 return session[token_key]
119
119
120
120
121 class _GetError(object):
121 class _GetError(object):
122 """Get error from form_errors, and represent it as span wrapped error
122 """Get error from form_errors, and represent it as span wrapped error
123 message
123 message
124
124
125 :param field_name: field to fetch errors for
125 :param field_name: field to fetch errors for
126 :param form_errors: form errors dict
126 :param form_errors: form errors dict
127 """
127 """
128
128
129 def __call__(self, field_name, form_errors):
129 def __call__(self, field_name, form_errors):
130 tmpl = """<span class="error_msg">%s</span>"""
130 tmpl = """<span class="error_msg">%s</span>"""
131 if form_errors and field_name in form_errors:
131 if form_errors and field_name in form_errors:
132 return literal(tmpl % form_errors.get(field_name))
132 return literal(tmpl % form_errors.get(field_name))
133
133
134 get_error = _GetError()
134 get_error = _GetError()
135
135
136
136
137 class _ToolTip(object):
137 class _ToolTip(object):
138
138
139 def __call__(self, tooltip_title, trim_at=50):
139 def __call__(self, tooltip_title, trim_at=50):
140 """
140 """
141 Special function just to wrap our text into nice formatted
141 Special function just to wrap our text into nice formatted
142 autowrapped text
142 autowrapped text
143
143
144 :param tooltip_title:
144 :param tooltip_title:
145 """
145 """
146 tooltip_title = escape(tooltip_title)
146 tooltip_title = escape(tooltip_title)
147 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
147 tooltip_title = tooltip_title.replace('<', '&lt;').replace('>', '&gt;')
148 return tooltip_title
148 return tooltip_title
149 tooltip = _ToolTip()
149 tooltip = _ToolTip()
150
150
151
151
152 class _FilesBreadCrumbs(object):
152 class _FilesBreadCrumbs(object):
153
153
154 def __call__(self, repo_name, rev, paths):
154 def __call__(self, repo_name, rev, paths):
155 if isinstance(paths, str):
155 if isinstance(paths, str):
156 paths = safe_unicode(paths)
156 paths = safe_unicode(paths)
157 url_l = [link_to(repo_name, url('files_home',
157 url_l = [link_to(repo_name, url('files_home',
158 repo_name=repo_name,
158 repo_name=repo_name,
159 revision=rev, f_path=''),
159 revision=rev, f_path=''),
160 class_='ypjax-link')]
160 class_='ypjax-link')]
161 paths_l = paths.split('/')
161 paths_l = paths.split('/')
162 for cnt, p in enumerate(paths_l):
162 for cnt, p in enumerate(paths_l):
163 if p != '':
163 if p != '':
164 url_l.append(link_to(p,
164 url_l.append(link_to(p,
165 url('files_home',
165 url('files_home',
166 repo_name=repo_name,
166 repo_name=repo_name,
167 revision=rev,
167 revision=rev,
168 f_path='/'.join(paths_l[:cnt + 1])
168 f_path='/'.join(paths_l[:cnt + 1])
169 ),
169 ),
170 class_='ypjax-link'
170 class_='ypjax-link'
171 )
171 )
172 )
172 )
173
173
174 return literal('/'.join(url_l))
174 return literal('/'.join(url_l))
175
175
176 files_breadcrumbs = _FilesBreadCrumbs()
176 files_breadcrumbs = _FilesBreadCrumbs()
177
177
178
178
179 class CodeHtmlFormatter(HtmlFormatter):
179 class CodeHtmlFormatter(HtmlFormatter):
180 """
180 """
181 My code Html Formatter for source codes
181 My code Html Formatter for source codes
182 """
182 """
183
183
184 def wrap(self, source, outfile):
184 def wrap(self, source, outfile):
185 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
185 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
186
186
187 def _wrap_code(self, source):
187 def _wrap_code(self, source):
188 for cnt, it in enumerate(source):
188 for cnt, it in enumerate(source):
189 i, t = it
189 i, t = it
190 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
190 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
191 yield i, t
191 yield i, t
192
192
193 def _wrap_tablelinenos(self, inner):
193 def _wrap_tablelinenos(self, inner):
194 dummyoutfile = StringIO.StringIO()
194 dummyoutfile = StringIO.StringIO()
195 lncount = 0
195 lncount = 0
196 for t, line in inner:
196 for t, line in inner:
197 if t:
197 if t:
198 lncount += 1
198 lncount += 1
199 dummyoutfile.write(line)
199 dummyoutfile.write(line)
200
200
201 fl = self.linenostart
201 fl = self.linenostart
202 mw = len(str(lncount + fl - 1))
202 mw = len(str(lncount + fl - 1))
203 sp = self.linenospecial
203 sp = self.linenospecial
204 st = self.linenostep
204 st = self.linenostep
205 la = self.lineanchors
205 la = self.lineanchors
206 aln = self.anchorlinenos
206 aln = self.anchorlinenos
207 nocls = self.noclasses
207 nocls = self.noclasses
208 if sp:
208 if sp:
209 lines = []
209 lines = []
210
210
211 for i in range(fl, fl + lncount):
211 for i in range(fl, fl + lncount):
212 if i % st == 0:
212 if i % st == 0:
213 if i % sp == 0:
213 if i % sp == 0:
214 if aln:
214 if aln:
215 lines.append('<a href="#%s%d" class="special">%*d</a>' %
215 lines.append('<a href="#%s%d" class="special">%*d</a>' %
216 (la, i, mw, i))
216 (la, i, mw, i))
217 else:
217 else:
218 lines.append('<span class="special">%*d</span>' % (mw, i))
218 lines.append('<span class="special">%*d</span>' % (mw, i))
219 else:
219 else:
220 if aln:
220 if aln:
221 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
221 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
222 else:
222 else:
223 lines.append('%*d' % (mw, i))
223 lines.append('%*d' % (mw, i))
224 else:
224 else:
225 lines.append('')
225 lines.append('')
226 ls = '\n'.join(lines)
226 ls = '\n'.join(lines)
227 else:
227 else:
228 lines = []
228 lines = []
229 for i in range(fl, fl + lncount):
229 for i in range(fl, fl + lncount):
230 if i % st == 0:
230 if i % st == 0:
231 if aln:
231 if aln:
232 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
232 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
233 else:
233 else:
234 lines.append('%*d' % (mw, i))
234 lines.append('%*d' % (mw, i))
235 else:
235 else:
236 lines.append('')
236 lines.append('')
237 ls = '\n'.join(lines)
237 ls = '\n'.join(lines)
238
238
239 # in case you wonder about the seemingly redundant <div> here: since the
239 # in case you wonder about the seemingly redundant <div> here: since the
240 # content in the other cell also is wrapped in a div, some browsers in
240 # content in the other cell also is wrapped in a div, some browsers in
241 # some configurations seem to mess up the formatting...
241 # some configurations seem to mess up the formatting...
242 if nocls:
242 if nocls:
243 yield 0, ('<table class="%stable">' % self.cssclass +
243 yield 0, ('<table class="%stable">' % self.cssclass +
244 '<tr><td><div class="linenodiv" '
244 '<tr><td><div class="linenodiv" '
245 'style="background-color: #f0f0f0; padding-right: 10px">'
245 'style="background-color: #f0f0f0; padding-right: 10px">'
246 '<pre style="line-height: 125%">' +
246 '<pre style="line-height: 125%">' +
247 ls + '</pre></div></td><td id="hlcode" class="code">')
247 ls + '</pre></div></td><td id="hlcode" class="code">')
248 else:
248 else:
249 yield 0, ('<table class="%stable">' % self.cssclass +
249 yield 0, ('<table class="%stable">' % self.cssclass +
250 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
250 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
251 ls + '</pre></div></td><td id="hlcode" class="code">')
251 ls + '</pre></div></td><td id="hlcode" class="code">')
252 yield 0, dummyoutfile.getvalue()
252 yield 0, dummyoutfile.getvalue()
253 yield 0, '</td></tr></table>'
253 yield 0, '</td></tr></table>'
254
254
255
255
256 def pygmentize(filenode, **kwargs):
256 def pygmentize(filenode, **kwargs):
257 """
257 """
258 pygmentize function using pygments
258 pygmentize function using pygments
259
259
260 :param filenode:
260 :param filenode:
261 """
261 """
262 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
262 lexer = get_custom_lexer(filenode.extension) or filenode.lexer
263 return literal(code_highlight(filenode.content, lexer,
263 return literal(code_highlight(filenode.content, lexer,
264 CodeHtmlFormatter(**kwargs)))
264 CodeHtmlFormatter(**kwargs)))
265
265
266
266
267 def pygmentize_annotation(repo_name, filenode, **kwargs):
267 def pygmentize_annotation(repo_name, filenode, **kwargs):
268 """
268 """
269 pygmentize function for annotation
269 pygmentize function for annotation
270
270
271 :param filenode:
271 :param filenode:
272 """
272 """
273
273
274 color_dict = {}
274 color_dict = {}
275
275
276 def gen_color(n=10000):
276 def gen_color(n=10000):
277 """generator for getting n of evenly distributed colors using
277 """generator for getting n of evenly distributed colors using
278 hsv color and golden ratio. It always return same order of colors
278 hsv color and golden ratio. It always return same order of colors
279
279
280 :returns: RGB tuple
280 :returns: RGB tuple
281 """
281 """
282
282
283 def hsv_to_rgb(h, s, v):
283 def hsv_to_rgb(h, s, v):
284 if s == 0.0:
284 if s == 0.0:
285 return v, v, v
285 return v, v, v
286 i = int(h * 6.0) # XXX assume int() truncates!
286 i = int(h * 6.0) # XXX assume int() truncates!
287 f = (h * 6.0) - i
287 f = (h * 6.0) - i
288 p = v * (1.0 - s)
288 p = v * (1.0 - s)
289 q = v * (1.0 - s * f)
289 q = v * (1.0 - s * f)
290 t = v * (1.0 - s * (1.0 - f))
290 t = v * (1.0 - s * (1.0 - f))
291 i = i % 6
291 i = i % 6
292 if i == 0:
292 if i == 0:
293 return v, t, p
293 return v, t, p
294 if i == 1:
294 if i == 1:
295 return q, v, p
295 return q, v, p
296 if i == 2:
296 if i == 2:
297 return p, v, t
297 return p, v, t
298 if i == 3:
298 if i == 3:
299 return p, q, v
299 return p, q, v
300 if i == 4:
300 if i == 4:
301 return t, p, v
301 return t, p, v
302 if i == 5:
302 if i == 5:
303 return v, p, q
303 return v, p, q
304
304
305 golden_ratio = 0.618033988749895
305 golden_ratio = 0.618033988749895
306 h = 0.22717784590367374
306 h = 0.22717784590367374
307
307
308 for _ in xrange(n):
308 for _ in xrange(n):
309 h += golden_ratio
309 h += golden_ratio
310 h %= 1
310 h %= 1
311 HSV_tuple = [h, 0.95, 0.95]
311 HSV_tuple = [h, 0.95, 0.95]
312 RGB_tuple = hsv_to_rgb(*HSV_tuple)
312 RGB_tuple = hsv_to_rgb(*HSV_tuple)
313 yield map(lambda x: str(int(x * 256)), RGB_tuple)
313 yield map(lambda x: str(int(x * 256)), RGB_tuple)
314
314
315 cgenerator = gen_color()
315 cgenerator = gen_color()
316
316
317 def get_color_string(cs):
317 def get_color_string(cs):
318 if cs in color_dict:
318 if cs in color_dict:
319 col = color_dict[cs]
319 col = color_dict[cs]
320 else:
320 else:
321 col = color_dict[cs] = cgenerator.next()
321 col = color_dict[cs] = cgenerator.next()
322 return "color: rgb(%s)! important;" % (', '.join(col))
322 return "color: rgb(%s)! important;" % (', '.join(col))
323
323
324 def url_func(repo_name):
324 def url_func(repo_name):
325
325
326 def _url_func(changeset):
326 def _url_func(changeset):
327 author = changeset.author
327 author = changeset.author
328 date = changeset.date
328 date = changeset.date
329 message = tooltip(changeset.message)
329 message = tooltip(changeset.message)
330
330
331 tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
331 tooltip_html = ("<div style='font-size:0.8em'><b>Author:</b>"
332 " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
332 " %s<br/><b>Date:</b> %s</b><br/><b>Message:"
333 "</b> %s<br/></div>")
333 "</b> %s<br/></div>")
334
334
335 tooltip_html = tooltip_html % (author, date, message)
335 tooltip_html = tooltip_html % (author, date, message)
336 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
336 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
337 short_id(changeset.raw_id))
337 short_id(changeset.raw_id))
338 uri = link_to(
338 uri = link_to(
339 lnk_format,
339 lnk_format,
340 url('changeset_home', repo_name=repo_name,
340 url('changeset_home', repo_name=repo_name,
341 revision=changeset.raw_id),
341 revision=changeset.raw_id),
342 style=get_color_string(changeset.raw_id),
342 style=get_color_string(changeset.raw_id),
343 class_='tooltip',
343 class_='tooltip',
344 title=tooltip_html
344 title=tooltip_html
345 )
345 )
346
346
347 uri += '\n'
347 uri += '\n'
348 return uri
348 return uri
349 return _url_func
349 return _url_func
350
350
351 return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
351 return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
352
352
353
353
354 def is_following_repo(repo_name, user_id):
354 def is_following_repo(repo_name, user_id):
355 from rhodecode.model.scm import ScmModel
355 from rhodecode.model.scm import ScmModel
356 return ScmModel().is_following_repo(repo_name, user_id)
356 return ScmModel().is_following_repo(repo_name, user_id)
357
357
358 flash = _Flash()
358 flash = _Flash()
359
359
360 #==============================================================================
360 #==============================================================================
361 # SCM FILTERS available via h.
361 # SCM FILTERS available via h.
362 #==============================================================================
362 #==============================================================================
363 from rhodecode.lib.vcs.utils import author_name, author_email
363 from rhodecode.lib.vcs.utils import author_name, author_email
364 from rhodecode.lib.utils2 import credentials_filter, age as _age
364 from rhodecode.lib.utils2 import credentials_filter, age as _age
365 from rhodecode.model.db import User, ChangesetStatus
365 from rhodecode.model.db import User, ChangesetStatus
366
366
367 age = lambda x, y=False: _age(x, y)
367 age = lambda x, y=False: _age(x, y)
368 capitalize = lambda x: x.capitalize()
368 capitalize = lambda x: x.capitalize()
369 email = author_email
369 email = author_email
370 short_id = lambda x: x[:12]
370 short_id = lambda x: x[:12]
371 hide_credentials = lambda x: ''.join(credentials_filter(x))
371 hide_credentials = lambda x: ''.join(credentials_filter(x))
372
372
373
373
374 def show_id(cs):
374 def show_id(cs):
375 """
375 """
376 Configurable function that shows ID
376 Configurable function that shows ID
377 by default it's r123:fffeeefffeee
377 by default it's r123:fffeeefffeee
378
378
379 :param cs: changeset instance
379 :param cs: changeset instance
380 """
380 """
381 from rhodecode import CONFIG
381 from rhodecode import CONFIG
382 def_len = safe_int(CONFIG.get('sha_len', 12))
382 def_len = safe_int(CONFIG.get('show_sha_length', 12))
383 show_rev = str2bool(CONFIG.get('sha_show_numeric_rev', True))
383 show_rev = str2bool(CONFIG.get('show_revision_number', True))
384
384
385 raw_id = cs.raw_id[:def_len]
385 raw_id = cs.raw_id[:def_len]
386 if show_rev:
386 if show_rev:
387 return 'r%s:%s' % (cs.revision, raw_id)
387 return 'r%s:%s' % (cs.revision, raw_id)
388 else:
388 else:
389 return '%s' % (raw_id)
389 return '%s' % (raw_id)
390
390
391
391
392 def fmt_date(date):
392 def fmt_date(date):
393 if date:
393 if date:
394 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
394 _fmt = _(u"%a, %d %b %Y %H:%M:%S").encode('utf8')
395 return date.strftime(_fmt).decode('utf8')
395 return date.strftime(_fmt).decode('utf8')
396
396
397 return ""
397 return ""
398
398
399
399
400 def is_git(repository):
400 def is_git(repository):
401 if hasattr(repository, 'alias'):
401 if hasattr(repository, 'alias'):
402 _type = repository.alias
402 _type = repository.alias
403 elif hasattr(repository, 'repo_type'):
403 elif hasattr(repository, 'repo_type'):
404 _type = repository.repo_type
404 _type = repository.repo_type
405 else:
405 else:
406 _type = repository
406 _type = repository
407 return _type == 'git'
407 return _type == 'git'
408
408
409
409
410 def is_hg(repository):
410 def is_hg(repository):
411 if hasattr(repository, 'alias'):
411 if hasattr(repository, 'alias'):
412 _type = repository.alias
412 _type = repository.alias
413 elif hasattr(repository, 'repo_type'):
413 elif hasattr(repository, 'repo_type'):
414 _type = repository.repo_type
414 _type = repository.repo_type
415 else:
415 else:
416 _type = repository
416 _type = repository
417 return _type == 'hg'
417 return _type == 'hg'
418
418
419
419
420 def email_or_none(author):
420 def email_or_none(author):
421 # extract email from the commit string
421 # extract email from the commit string
422 _email = email(author)
422 _email = email(author)
423 if _email != '':
423 if _email != '':
424 # check it against RhodeCode database, and use the MAIN email for this
424 # check it against RhodeCode database, and use the MAIN email for this
425 # user
425 # user
426 user = User.get_by_email(_email, case_insensitive=True, cache=True)
426 user = User.get_by_email(_email, case_insensitive=True, cache=True)
427 if user is not None:
427 if user is not None:
428 return user.email
428 return user.email
429 return _email
429 return _email
430
430
431 # See if it contains a username we can get an email from
431 # See if it contains a username we can get an email from
432 user = User.get_by_username(author_name(author), case_insensitive=True,
432 user = User.get_by_username(author_name(author), case_insensitive=True,
433 cache=True)
433 cache=True)
434 if user is not None:
434 if user is not None:
435 return user.email
435 return user.email
436
436
437 # No valid email, not a valid user in the system, none!
437 # No valid email, not a valid user in the system, none!
438 return None
438 return None
439
439
440
440
441 def person(author, show_attr="username_and_name"):
441 def person(author, show_attr="username_and_name"):
442 # attr to return from fetched user
442 # attr to return from fetched user
443 person_getter = lambda usr: getattr(usr, show_attr)
443 person_getter = lambda usr: getattr(usr, show_attr)
444
444
445 # Valid email in the attribute passed, see if they're in the system
445 # Valid email in the attribute passed, see if they're in the system
446 _email = email(author)
446 _email = email(author)
447 if _email != '':
447 if _email != '':
448 user = User.get_by_email(_email, case_insensitive=True, cache=True)
448 user = User.get_by_email(_email, case_insensitive=True, cache=True)
449 if user is not None:
449 if user is not None:
450 return person_getter(user)
450 return person_getter(user)
451 return _email
451 return _email
452
452
453 # Maybe it's a username?
453 # Maybe it's a username?
454 _author = author_name(author)
454 _author = author_name(author)
455 user = User.get_by_username(_author, case_insensitive=True,
455 user = User.get_by_username(_author, case_insensitive=True,
456 cache=True)
456 cache=True)
457 if user is not None:
457 if user is not None:
458 return person_getter(user)
458 return person_getter(user)
459
459
460 # Still nothing? Just pass back the author name then
460 # Still nothing? Just pass back the author name then
461 return _author
461 return _author
462
462
463
463
464 def person_by_id(id_, show_attr="username_and_name"):
464 def person_by_id(id_, show_attr="username_and_name"):
465 # attr to return from fetched user
465 # attr to return from fetched user
466 person_getter = lambda usr: getattr(usr, show_attr)
466 person_getter = lambda usr: getattr(usr, show_attr)
467
467
468 #maybe it's an ID ?
468 #maybe it's an ID ?
469 if str(id_).isdigit() or isinstance(id_, int):
469 if str(id_).isdigit() or isinstance(id_, int):
470 id_ = int(id_)
470 id_ = int(id_)
471 user = User.get(id_)
471 user = User.get(id_)
472 if user is not None:
472 if user is not None:
473 return person_getter(user)
473 return person_getter(user)
474 return id_
474 return id_
475
475
476
476
477 def desc_stylize(value):
477 def desc_stylize(value):
478 """
478 """
479 converts tags from value into html equivalent
479 converts tags from value into html equivalent
480
480
481 :param value:
481 :param value:
482 """
482 """
483 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
483 value = re.sub(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
484 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
484 '<div class="metatag" tag="see">see =&gt; \\1 </div>', value)
485 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
485 value = re.sub(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]',
486 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
486 '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', value)
487 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
487 value = re.sub(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]',
488 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
488 '<div class="metatag" tag="\\1">\\1 =&gt; <a href="/\\2">\\2</a></div>', value)
489 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
489 value = re.sub(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+]*)\]',
490 '<div class="metatag" tag="lang">\\2</div>', value)
490 '<div class="metatag" tag="lang">\\2</div>', value)
491 value = re.sub(r'\[([a-z]+)\]',
491 value = re.sub(r'\[([a-z]+)\]',
492 '<div class="metatag" tag="\\1">\\1</div>', value)
492 '<div class="metatag" tag="\\1">\\1</div>', value)
493
493
494 return value
494 return value
495
495
496
496
497 def boolicon(value):
497 def boolicon(value):
498 """Returns boolean value of a value, represented as small html image of true/false
498 """Returns boolean value of a value, represented as small html image of true/false
499 icons
499 icons
500
500
501 :param value: value
501 :param value: value
502 """
502 """
503
503
504 if value:
504 if value:
505 return HTML.tag('img', src=url("/images/icons/accept.png"),
505 return HTML.tag('img', src=url("/images/icons/accept.png"),
506 alt=_('True'))
506 alt=_('True'))
507 else:
507 else:
508 return HTML.tag('img', src=url("/images/icons/cancel.png"),
508 return HTML.tag('img', src=url("/images/icons/cancel.png"),
509 alt=_('False'))
509 alt=_('False'))
510
510
511
511
512 def action_parser(user_log, feed=False, parse_cs=False):
512 def action_parser(user_log, feed=False, parse_cs=False):
513 """
513 """
514 This helper will action_map the specified string action into translated
514 This helper will action_map the specified string action into translated
515 fancy names with icons and links
515 fancy names with icons and links
516
516
517 :param user_log: user log instance
517 :param user_log: user log instance
518 :param feed: use output for feeds (no html and fancy icons)
518 :param feed: use output for feeds (no html and fancy icons)
519 :param parse_cs: parse Changesets into VCS instances
519 :param parse_cs: parse Changesets into VCS instances
520 """
520 """
521
521
522 action = user_log.action
522 action = user_log.action
523 action_params = ' '
523 action_params = ' '
524
524
525 x = action.split(':')
525 x = action.split(':')
526
526
527 if len(x) > 1:
527 if len(x) > 1:
528 action, action_params = x
528 action, action_params = x
529
529
530 def get_cs_links():
530 def get_cs_links():
531 revs_limit = 3 # display this amount always
531 revs_limit = 3 # display this amount always
532 revs_top_limit = 50 # show upto this amount of changesets hidden
532 revs_top_limit = 50 # show upto this amount of changesets hidden
533 revs_ids = action_params.split(',')
533 revs_ids = action_params.split(',')
534 deleted = user_log.repository is None
534 deleted = user_log.repository is None
535 if deleted:
535 if deleted:
536 return ','.join(revs_ids)
536 return ','.join(revs_ids)
537
537
538 repo_name = user_log.repository.repo_name
538 repo_name = user_log.repository.repo_name
539
539
540 def lnk(rev, repo_name):
540 def lnk(rev, repo_name):
541 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
541 if isinstance(rev, BaseChangeset) or isinstance(rev, AttributeDict):
542 lazy_cs = True
542 lazy_cs = True
543 if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
543 if getattr(rev, 'op', None) and getattr(rev, 'ref_name', None):
544 lazy_cs = False
544 lazy_cs = False
545 lbl = '?'
545 lbl = '?'
546 if rev.op == 'delete_branch':
546 if rev.op == 'delete_branch':
547 lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
547 lbl = '%s' % _('Deleted branch: %s') % rev.ref_name
548 title = ''
548 title = ''
549 elif rev.op == 'tag':
549 elif rev.op == 'tag':
550 lbl = '%s' % _('Created tag: %s') % rev.ref_name
550 lbl = '%s' % _('Created tag: %s') % rev.ref_name
551 title = ''
551 title = ''
552 _url = '#'
552 _url = '#'
553
553
554 else:
554 else:
555 lbl = '%s' % (rev.short_id[:8])
555 lbl = '%s' % (rev.short_id[:8])
556 _url = url('changeset_home', repo_name=repo_name,
556 _url = url('changeset_home', repo_name=repo_name,
557 revision=rev.raw_id)
557 revision=rev.raw_id)
558 title = tooltip(rev.message)
558 title = tooltip(rev.message)
559 else:
559 else:
560 ## changeset cannot be found/striped/removed etc.
560 ## changeset cannot be found/striped/removed etc.
561 lbl = ('%s' % rev)[:12]
561 lbl = ('%s' % rev)[:12]
562 _url = '#'
562 _url = '#'
563 title = _('Changeset not found')
563 title = _('Changeset not found')
564 if parse_cs:
564 if parse_cs:
565 return link_to(lbl, _url, title=title, class_='tooltip')
565 return link_to(lbl, _url, title=title, class_='tooltip')
566 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
566 return link_to(lbl, _url, raw_id=rev.raw_id, repo_name=repo_name,
567 class_='lazy-cs' if lazy_cs else '')
567 class_='lazy-cs' if lazy_cs else '')
568
568
569 def _get_op(rev_txt):
569 def _get_op(rev_txt):
570 _op = None
570 _op = None
571 _name = rev_txt
571 _name = rev_txt
572 if len(rev_txt.split('=>')) == 2:
572 if len(rev_txt.split('=>')) == 2:
573 _op, _name = rev_txt.split('=>')
573 _op, _name = rev_txt.split('=>')
574 return _op, _name
574 return _op, _name
575
575
576 revs = []
576 revs = []
577 if len(filter(lambda v: v != '', revs_ids)) > 0:
577 if len(filter(lambda v: v != '', revs_ids)) > 0:
578 repo = None
578 repo = None
579 for rev in revs_ids[:revs_top_limit]:
579 for rev in revs_ids[:revs_top_limit]:
580 _op, _name = _get_op(rev)
580 _op, _name = _get_op(rev)
581
581
582 # we want parsed changesets, or new log store format is bad
582 # we want parsed changesets, or new log store format is bad
583 if parse_cs:
583 if parse_cs:
584 try:
584 try:
585 if repo is None:
585 if repo is None:
586 repo = user_log.repository.scm_instance
586 repo = user_log.repository.scm_instance
587 _rev = repo.get_changeset(rev)
587 _rev = repo.get_changeset(rev)
588 revs.append(_rev)
588 revs.append(_rev)
589 except ChangesetDoesNotExistError:
589 except ChangesetDoesNotExistError:
590 log.error('cannot find revision %s in this repo' % rev)
590 log.error('cannot find revision %s in this repo' % rev)
591 revs.append(rev)
591 revs.append(rev)
592 continue
592 continue
593 else:
593 else:
594 _rev = AttributeDict({
594 _rev = AttributeDict({
595 'short_id': rev[:12],
595 'short_id': rev[:12],
596 'raw_id': rev,
596 'raw_id': rev,
597 'message': '',
597 'message': '',
598 'op': _op,
598 'op': _op,
599 'ref_name': _name
599 'ref_name': _name
600 })
600 })
601 revs.append(_rev)
601 revs.append(_rev)
602 cs_links = []
602 cs_links = []
603 cs_links.append(" " + ', '.join(
603 cs_links.append(" " + ', '.join(
604 [lnk(rev, repo_name) for rev in revs[:revs_limit]]
604 [lnk(rev, repo_name) for rev in revs[:revs_limit]]
605 )
605 )
606 )
606 )
607 _op1, _name1 = _get_op(revs_ids[0])
607 _op1, _name1 = _get_op(revs_ids[0])
608 _op2, _name2 = _get_op(revs_ids[-1])
608 _op2, _name2 = _get_op(revs_ids[-1])
609
609
610 _rev = '%s...%s' % (_name1, _name2)
610 _rev = '%s...%s' % (_name1, _name2)
611
611
612 compare_view = (
612 compare_view = (
613 ' <div class="compare_view tooltip" title="%s">'
613 ' <div class="compare_view tooltip" title="%s">'
614 '<a href="%s">%s</a> </div>' % (
614 '<a href="%s">%s</a> </div>' % (
615 _('Show all combined changesets %s->%s') % (
615 _('Show all combined changesets %s->%s') % (
616 revs_ids[0][:12], revs_ids[-1][:12]
616 revs_ids[0][:12], revs_ids[-1][:12]
617 ),
617 ),
618 url('changeset_home', repo_name=repo_name,
618 url('changeset_home', repo_name=repo_name,
619 revision=_rev
619 revision=_rev
620 ),
620 ),
621 _('compare view')
621 _('compare view')
622 )
622 )
623 )
623 )
624
624
625 # if we have exactly one more than normally displayed
625 # if we have exactly one more than normally displayed
626 # just display it, takes less space than displaying
626 # just display it, takes less space than displaying
627 # "and 1 more revisions"
627 # "and 1 more revisions"
628 if len(revs_ids) == revs_limit + 1:
628 if len(revs_ids) == revs_limit + 1:
629 rev = revs[revs_limit]
629 rev = revs[revs_limit]
630 cs_links.append(", " + lnk(rev, repo_name))
630 cs_links.append(", " + lnk(rev, repo_name))
631
631
632 # hidden-by-default ones
632 # hidden-by-default ones
633 if len(revs_ids) > revs_limit + 1:
633 if len(revs_ids) > revs_limit + 1:
634 uniq_id = revs_ids[0]
634 uniq_id = revs_ids[0]
635 html_tmpl = (
635 html_tmpl = (
636 '<span> %s <a class="show_more" id="_%s" '
636 '<span> %s <a class="show_more" id="_%s" '
637 'href="#more">%s</a> %s</span>'
637 'href="#more">%s</a> %s</span>'
638 )
638 )
639 if not feed:
639 if not feed:
640 cs_links.append(html_tmpl % (
640 cs_links.append(html_tmpl % (
641 _('and'),
641 _('and'),
642 uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
642 uniq_id, _('%s more') % (len(revs_ids) - revs_limit),
643 _('revisions')
643 _('revisions')
644 )
644 )
645 )
645 )
646
646
647 if not feed:
647 if not feed:
648 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
648 html_tmpl = '<span id="%s" style="display:none">, %s </span>'
649 else:
649 else:
650 html_tmpl = '<span id="%s"> %s </span>'
650 html_tmpl = '<span id="%s"> %s </span>'
651
651
652 morelinks = ', '.join(
652 morelinks = ', '.join(
653 [lnk(rev, repo_name) for rev in revs[revs_limit:]]
653 [lnk(rev, repo_name) for rev in revs[revs_limit:]]
654 )
654 )
655
655
656 if len(revs_ids) > revs_top_limit:
656 if len(revs_ids) > revs_top_limit:
657 morelinks += ', ...'
657 morelinks += ', ...'
658
658
659 cs_links.append(html_tmpl % (uniq_id, morelinks))
659 cs_links.append(html_tmpl % (uniq_id, morelinks))
660 if len(revs) > 1:
660 if len(revs) > 1:
661 cs_links.append(compare_view)
661 cs_links.append(compare_view)
662 return ''.join(cs_links)
662 return ''.join(cs_links)
663
663
664 def get_fork_name():
664 def get_fork_name():
665 repo_name = action_params
665 repo_name = action_params
666 _url = url('summary_home', repo_name=repo_name)
666 _url = url('summary_home', repo_name=repo_name)
667 return _('fork name %s') % link_to(action_params, _url)
667 return _('fork name %s') % link_to(action_params, _url)
668
668
669 def get_user_name():
669 def get_user_name():
670 user_name = action_params
670 user_name = action_params
671 return user_name
671 return user_name
672
672
673 def get_users_group():
673 def get_users_group():
674 group_name = action_params
674 group_name = action_params
675 return group_name
675 return group_name
676
676
677 def get_pull_request():
677 def get_pull_request():
678 pull_request_id = action_params
678 pull_request_id = action_params
679 deleted = user_log.repository is None
679 deleted = user_log.repository is None
680 if deleted:
680 if deleted:
681 repo_name = user_log.repository_name
681 repo_name = user_log.repository_name
682 else:
682 else:
683 repo_name = user_log.repository.repo_name
683 repo_name = user_log.repository.repo_name
684 return link_to(_('Pull request #%s') % pull_request_id,
684 return link_to(_('Pull request #%s') % pull_request_id,
685 url('pullrequest_show', repo_name=repo_name,
685 url('pullrequest_show', repo_name=repo_name,
686 pull_request_id=pull_request_id))
686 pull_request_id=pull_request_id))
687
687
688 # action : translated str, callback(extractor), icon
688 # action : translated str, callback(extractor), icon
689 action_map = {
689 action_map = {
690 'user_deleted_repo': (_('[deleted] repository'),
690 'user_deleted_repo': (_('[deleted] repository'),
691 None, 'database_delete.png'),
691 None, 'database_delete.png'),
692 'user_created_repo': (_('[created] repository'),
692 'user_created_repo': (_('[created] repository'),
693 None, 'database_add.png'),
693 None, 'database_add.png'),
694 'user_created_fork': (_('[created] repository as fork'),
694 'user_created_fork': (_('[created] repository as fork'),
695 None, 'arrow_divide.png'),
695 None, 'arrow_divide.png'),
696 'user_forked_repo': (_('[forked] repository'),
696 'user_forked_repo': (_('[forked] repository'),
697 get_fork_name, 'arrow_divide.png'),
697 get_fork_name, 'arrow_divide.png'),
698 'user_updated_repo': (_('[updated] repository'),
698 'user_updated_repo': (_('[updated] repository'),
699 None, 'database_edit.png'),
699 None, 'database_edit.png'),
700 'admin_deleted_repo': (_('[delete] repository'),
700 'admin_deleted_repo': (_('[delete] repository'),
701 None, 'database_delete.png'),
701 None, 'database_delete.png'),
702 'admin_created_repo': (_('[created] repository'),
702 'admin_created_repo': (_('[created] repository'),
703 None, 'database_add.png'),
703 None, 'database_add.png'),
704 'admin_forked_repo': (_('[forked] repository'),
704 'admin_forked_repo': (_('[forked] repository'),
705 None, 'arrow_divide.png'),
705 None, 'arrow_divide.png'),
706 'admin_updated_repo': (_('[updated] repository'),
706 'admin_updated_repo': (_('[updated] repository'),
707 None, 'database_edit.png'),
707 None, 'database_edit.png'),
708 'admin_created_user': (_('[created] user'),
708 'admin_created_user': (_('[created] user'),
709 get_user_name, 'user_add.png'),
709 get_user_name, 'user_add.png'),
710 'admin_updated_user': (_('[updated] user'),
710 'admin_updated_user': (_('[updated] user'),
711 get_user_name, 'user_edit.png'),
711 get_user_name, 'user_edit.png'),
712 'admin_created_users_group': (_('[created] user group'),
712 'admin_created_users_group': (_('[created] user group'),
713 get_users_group, 'group_add.png'),
713 get_users_group, 'group_add.png'),
714 'admin_updated_users_group': (_('[updated] user group'),
714 'admin_updated_users_group': (_('[updated] user group'),
715 get_users_group, 'group_edit.png'),
715 get_users_group, 'group_edit.png'),
716 'user_commented_revision': (_('[commented] on revision in repository'),
716 'user_commented_revision': (_('[commented] on revision in repository'),
717 get_cs_links, 'comment_add.png'),
717 get_cs_links, 'comment_add.png'),
718 'user_commented_pull_request': (_('[commented] on pull request for'),
718 'user_commented_pull_request': (_('[commented] on pull request for'),
719 get_pull_request, 'comment_add.png'),
719 get_pull_request, 'comment_add.png'),
720 'user_closed_pull_request': (_('[closed] pull request for'),
720 'user_closed_pull_request': (_('[closed] pull request for'),
721 get_pull_request, 'tick.png'),
721 get_pull_request, 'tick.png'),
722 'push': (_('[pushed] into'),
722 'push': (_('[pushed] into'),
723 get_cs_links, 'script_add.png'),
723 get_cs_links, 'script_add.png'),
724 'push_local': (_('[committed via RhodeCode] into repository'),
724 'push_local': (_('[committed via RhodeCode] into repository'),
725 get_cs_links, 'script_edit.png'),
725 get_cs_links, 'script_edit.png'),
726 'push_remote': (_('[pulled from remote] into repository'),
726 'push_remote': (_('[pulled from remote] into repository'),
727 get_cs_links, 'connect.png'),
727 get_cs_links, 'connect.png'),
728 'pull': (_('[pulled] from'),
728 'pull': (_('[pulled] from'),
729 None, 'down_16.png'),
729 None, 'down_16.png'),
730 'started_following_repo': (_('[started following] repository'),
730 'started_following_repo': (_('[started following] repository'),
731 None, 'heart_add.png'),
731 None, 'heart_add.png'),
732 'stopped_following_repo': (_('[stopped following] repository'),
732 'stopped_following_repo': (_('[stopped following] repository'),
733 None, 'heart_delete.png'),
733 None, 'heart_delete.png'),
734 }
734 }
735
735
736 action_str = action_map.get(action, action)
736 action_str = action_map.get(action, action)
737 if feed:
737 if feed:
738 action = action_str[0].replace('[', '').replace(']', '')
738 action = action_str[0].replace('[', '').replace(']', '')
739 else:
739 else:
740 action = action_str[0]\
740 action = action_str[0]\
741 .replace('[', '<span class="journal_highlight">')\
741 .replace('[', '<span class="journal_highlight">')\
742 .replace(']', '</span>')
742 .replace(']', '</span>')
743
743
744 action_params_func = lambda: ""
744 action_params_func = lambda: ""
745
745
746 if callable(action_str[1]):
746 if callable(action_str[1]):
747 action_params_func = action_str[1]
747 action_params_func = action_str[1]
748
748
749 def action_parser_icon():
749 def action_parser_icon():
750 action = user_log.action
750 action = user_log.action
751 action_params = None
751 action_params = None
752 x = action.split(':')
752 x = action.split(':')
753
753
754 if len(x) > 1:
754 if len(x) > 1:
755 action, action_params = x
755 action, action_params = x
756
756
757 tmpl = """<img src="%s%s" alt="%s"/>"""
757 tmpl = """<img src="%s%s" alt="%s"/>"""
758 ico = action_map.get(action, ['', '', ''])[2]
758 ico = action_map.get(action, ['', '', ''])[2]
759 return literal(tmpl % ((url('/images/icons/')), ico, action))
759 return literal(tmpl % ((url('/images/icons/')), ico, action))
760
760
761 # returned callbacks we need to call to get
761 # returned callbacks we need to call to get
762 return [lambda: literal(action), action_params_func, action_parser_icon]
762 return [lambda: literal(action), action_params_func, action_parser_icon]
763
763
764
764
765
765
766 #==============================================================================
766 #==============================================================================
767 # PERMS
767 # PERMS
768 #==============================================================================
768 #==============================================================================
769 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
769 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
770 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
770 HasRepoPermissionAny, HasRepoPermissionAll, HasReposGroupPermissionAll, \
771 HasReposGroupPermissionAny
771 HasReposGroupPermissionAny
772
772
773
773
774 #==============================================================================
774 #==============================================================================
775 # GRAVATAR URL
775 # GRAVATAR URL
776 #==============================================================================
776 #==============================================================================
777
777
778 def gravatar_url(email_address, size=30):
778 def gravatar_url(email_address, size=30):
779 from pylons import url # doh, we need to re-import url to mock it later
779 from pylons import url # doh, we need to re-import url to mock it later
780 _def = 'anonymous@rhodecode.org'
780 _def = 'anonymous@rhodecode.org'
781 use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
781 use_gravatar = str2bool(config['app_conf'].get('use_gravatar'))
782 email_address = email_address or _def
782 email_address = email_address or _def
783 if (not use_gravatar or not email_address or email_address == _def):
783 if (not use_gravatar or not email_address or email_address == _def):
784 f = lambda a, l: min(l, key=lambda x: abs(x - a))
784 f = lambda a, l: min(l, key=lambda x: abs(x - a))
785 return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
785 return url("/images/user%s.png" % f(size, [14, 16, 20, 24, 30]))
786
786
787 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
787 if use_gravatar and config['app_conf'].get('alternative_gravatar_url'):
788 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
788 tmpl = config['app_conf'].get('alternative_gravatar_url', '')
789 parsed_url = urlparse.urlparse(url.current(qualified=True))
789 parsed_url = urlparse.urlparse(url.current(qualified=True))
790 tmpl = tmpl.replace('{email}', email_address)\
790 tmpl = tmpl.replace('{email}', email_address)\
791 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
791 .replace('{md5email}', hashlib.md5(email_address.lower()).hexdigest()) \
792 .replace('{netloc}', parsed_url.netloc)\
792 .replace('{netloc}', parsed_url.netloc)\
793 .replace('{scheme}', parsed_url.scheme)\
793 .replace('{scheme}', parsed_url.scheme)\
794 .replace('{size}', str(size))
794 .replace('{size}', str(size))
795 return tmpl
795 return tmpl
796
796
797 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
797 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
798 default = 'identicon'
798 default = 'identicon'
799 baseurl_nossl = "http://www.gravatar.com/avatar/"
799 baseurl_nossl = "http://www.gravatar.com/avatar/"
800 baseurl_ssl = "https://secure.gravatar.com/avatar/"
800 baseurl_ssl = "https://secure.gravatar.com/avatar/"
801 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
801 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
802
802
803 if isinstance(email_address, unicode):
803 if isinstance(email_address, unicode):
804 #hashlib crashes on unicode items
804 #hashlib crashes on unicode items
805 email_address = safe_str(email_address)
805 email_address = safe_str(email_address)
806 # construct the url
806 # construct the url
807 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
807 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
808 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
808 gravatar_url += urllib.urlencode({'d': default, 's': str(size)})
809
809
810 return gravatar_url
810 return gravatar_url
811
811
812
812
813 #==============================================================================
813 #==============================================================================
814 # REPO PAGER, PAGER FOR REPOSITORY
814 # REPO PAGER, PAGER FOR REPOSITORY
815 #==============================================================================
815 #==============================================================================
816 class RepoPage(Page):
816 class RepoPage(Page):
817
817
818 def __init__(self, collection, page=1, items_per_page=20,
818 def __init__(self, collection, page=1, items_per_page=20,
819 item_count=None, url=None, **kwargs):
819 item_count=None, url=None, **kwargs):
820
820
821 """Create a "RepoPage" instance. special pager for paging
821 """Create a "RepoPage" instance. special pager for paging
822 repository
822 repository
823 """
823 """
824 self._url_generator = url
824 self._url_generator = url
825
825
826 # Safe the kwargs class-wide so they can be used in the pager() method
826 # Safe the kwargs class-wide so they can be used in the pager() method
827 self.kwargs = kwargs
827 self.kwargs = kwargs
828
828
829 # Save a reference to the collection
829 # Save a reference to the collection
830 self.original_collection = collection
830 self.original_collection = collection
831
831
832 self.collection = collection
832 self.collection = collection
833
833
834 # The self.page is the number of the current page.
834 # The self.page is the number of the current page.
835 # The first page has the number 1!
835 # The first page has the number 1!
836 try:
836 try:
837 self.page = int(page) # make it int() if we get it as a string
837 self.page = int(page) # make it int() if we get it as a string
838 except (ValueError, TypeError):
838 except (ValueError, TypeError):
839 self.page = 1
839 self.page = 1
840
840
841 self.items_per_page = items_per_page
841 self.items_per_page = items_per_page
842
842
843 # Unless the user tells us how many items the collections has
843 # Unless the user tells us how many items the collections has
844 # we calculate that ourselves.
844 # we calculate that ourselves.
845 if item_count is not None:
845 if item_count is not None:
846 self.item_count = item_count
846 self.item_count = item_count
847 else:
847 else:
848 self.item_count = len(self.collection)
848 self.item_count = len(self.collection)
849
849
850 # Compute the number of the first and last available page
850 # Compute the number of the first and last available page
851 if self.item_count > 0:
851 if self.item_count > 0:
852 self.first_page = 1
852 self.first_page = 1
853 self.page_count = int(math.ceil(float(self.item_count) /
853 self.page_count = int(math.ceil(float(self.item_count) /
854 self.items_per_page))
854 self.items_per_page))
855 self.last_page = self.first_page + self.page_count - 1
855 self.last_page = self.first_page + self.page_count - 1
856
856
857 # Make sure that the requested page number is the range of
857 # Make sure that the requested page number is the range of
858 # valid pages
858 # valid pages
859 if self.page > self.last_page:
859 if self.page > self.last_page:
860 self.page = self.last_page
860 self.page = self.last_page
861 elif self.page < self.first_page:
861 elif self.page < self.first_page:
862 self.page = self.first_page
862 self.page = self.first_page
863
863
864 # Note: the number of items on this page can be less than
864 # Note: the number of items on this page can be less than
865 # items_per_page if the last page is not full
865 # items_per_page if the last page is not full
866 self.first_item = max(0, (self.item_count) - (self.page *
866 self.first_item = max(0, (self.item_count) - (self.page *
867 items_per_page))
867 items_per_page))
868 self.last_item = ((self.item_count - 1) - items_per_page *
868 self.last_item = ((self.item_count - 1) - items_per_page *
869 (self.page - 1))
869 (self.page - 1))
870
870
871 self.items = list(self.collection[self.first_item:self.last_item + 1])
871 self.items = list(self.collection[self.first_item:self.last_item + 1])
872
872
873 # Links to previous and next page
873 # Links to previous and next page
874 if self.page > self.first_page:
874 if self.page > self.first_page:
875 self.previous_page = self.page - 1
875 self.previous_page = self.page - 1
876 else:
876 else:
877 self.previous_page = None
877 self.previous_page = None
878
878
879 if self.page < self.last_page:
879 if self.page < self.last_page:
880 self.next_page = self.page + 1
880 self.next_page = self.page + 1
881 else:
881 else:
882 self.next_page = None
882 self.next_page = None
883
883
884 # No items available
884 # No items available
885 else:
885 else:
886 self.first_page = None
886 self.first_page = None
887 self.page_count = 0
887 self.page_count = 0
888 self.last_page = None
888 self.last_page = None
889 self.first_item = None
889 self.first_item = None
890 self.last_item = None
890 self.last_item = None
891 self.previous_page = None
891 self.previous_page = None
892 self.next_page = None
892 self.next_page = None
893 self.items = []
893 self.items = []
894
894
895 # This is a subclass of the 'list' type. Initialise the list now.
895 # This is a subclass of the 'list' type. Initialise the list now.
896 list.__init__(self, reversed(self.items))
896 list.__init__(self, reversed(self.items))
897
897
898
898
899 def changed_tooltip(nodes):
899 def changed_tooltip(nodes):
900 """
900 """
901 Generates a html string for changed nodes in changeset page.
901 Generates a html string for changed nodes in changeset page.
902 It limits the output to 30 entries
902 It limits the output to 30 entries
903
903
904 :param nodes: LazyNodesGenerator
904 :param nodes: LazyNodesGenerator
905 """
905 """
906 if nodes:
906 if nodes:
907 pref = ': <br/> '
907 pref = ': <br/> '
908 suf = ''
908 suf = ''
909 if len(nodes) > 30:
909 if len(nodes) > 30:
910 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
910 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
911 return literal(pref + '<br/> '.join([safe_unicode(x.path)
911 return literal(pref + '<br/> '.join([safe_unicode(x.path)
912 for x in nodes[:30]]) + suf)
912 for x in nodes[:30]]) + suf)
913 else:
913 else:
914 return ': ' + _('No Files')
914 return ': ' + _('No Files')
915
915
916
916
917 def repo_link(groups_and_repos):
917 def repo_link(groups_and_repos):
918 """
918 """
919 Makes a breadcrumbs link to repo within a group
919 Makes a breadcrumbs link to repo within a group
920 joins &raquo; on each group to create a fancy link
920 joins &raquo; on each group to create a fancy link
921
921
922 ex::
922 ex::
923 group >> subgroup >> repo
923 group >> subgroup >> repo
924
924
925 :param groups_and_repos:
925 :param groups_and_repos:
926 :param last_url:
926 :param last_url:
927 """
927 """
928 groups, just_name, repo_name = groups_and_repos
928 groups, just_name, repo_name = groups_and_repos
929 last_url = url('summary_home', repo_name=repo_name)
929 last_url = url('summary_home', repo_name=repo_name)
930 last_link = link_to(just_name, last_url)
930 last_link = link_to(just_name, last_url)
931
931
932 def make_link(group):
932 def make_link(group):
933 return link_to(group.name,
933 return link_to(group.name,
934 url('repos_group_home', group_name=group.group_name))
934 url('repos_group_home', group_name=group.group_name))
935 return literal(' &raquo; '.join(map(make_link, groups) + ['<span>%s</span>' % last_link]))
935 return literal(' &raquo; '.join(map(make_link, groups) + ['<span>%s</span>' % last_link]))
936
936
937
937
938 def fancy_file_stats(stats):
938 def fancy_file_stats(stats):
939 """
939 """
940 Displays a fancy two colored bar for number of added/deleted
940 Displays a fancy two colored bar for number of added/deleted
941 lines of code on file
941 lines of code on file
942
942
943 :param stats: two element list of added/deleted lines of code
943 :param stats: two element list of added/deleted lines of code
944 """
944 """
945 def cgen(l_type, a_v, d_v):
945 def cgen(l_type, a_v, d_v):
946 mapping = {'tr': 'top-right-rounded-corner-mid',
946 mapping = {'tr': 'top-right-rounded-corner-mid',
947 'tl': 'top-left-rounded-corner-mid',
947 'tl': 'top-left-rounded-corner-mid',
948 'br': 'bottom-right-rounded-corner-mid',
948 'br': 'bottom-right-rounded-corner-mid',
949 'bl': 'bottom-left-rounded-corner-mid'}
949 'bl': 'bottom-left-rounded-corner-mid'}
950 map_getter = lambda x: mapping[x]
950 map_getter = lambda x: mapping[x]
951
951
952 if l_type == 'a' and d_v:
952 if l_type == 'a' and d_v:
953 #case when added and deleted are present
953 #case when added and deleted are present
954 return ' '.join(map(map_getter, ['tl', 'bl']))
954 return ' '.join(map(map_getter, ['tl', 'bl']))
955
955
956 if l_type == 'a' and not d_v:
956 if l_type == 'a' and not d_v:
957 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
957 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
958
958
959 if l_type == 'd' and a_v:
959 if l_type == 'd' and a_v:
960 return ' '.join(map(map_getter, ['tr', 'br']))
960 return ' '.join(map(map_getter, ['tr', 'br']))
961
961
962 if l_type == 'd' and not a_v:
962 if l_type == 'd' and not a_v:
963 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
963 return ' '.join(map(map_getter, ['tr', 'br', 'tl', 'bl']))
964
964
965 a, d = stats[0], stats[1]
965 a, d = stats[0], stats[1]
966 width = 100
966 width = 100
967
967
968 if a == 'b':
968 if a == 'b':
969 #binary mode
969 #binary mode
970 b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
970 b_d = '<div class="bin%s %s" style="width:100%%">%s</div>' % (d, cgen('a', a_v='', d_v=0), 'bin')
971 b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
971 b_a = '<div class="bin1" style="width:0%%">%s</div>' % ('bin')
972 return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
972 return literal('<div style="width:%spx">%s%s</div>' % (width, b_a, b_d))
973
973
974 t = stats[0] + stats[1]
974 t = stats[0] + stats[1]
975 unit = float(width) / (t or 1)
975 unit = float(width) / (t or 1)
976
976
977 # needs > 9% of width to be visible or 0 to be hidden
977 # needs > 9% of width to be visible or 0 to be hidden
978 a_p = max(9, unit * a) if a > 0 else 0
978 a_p = max(9, unit * a) if a > 0 else 0
979 d_p = max(9, unit * d) if d > 0 else 0
979 d_p = max(9, unit * d) if d > 0 else 0
980 p_sum = a_p + d_p
980 p_sum = a_p + d_p
981
981
982 if p_sum > width:
982 if p_sum > width:
983 #adjust the percentage to be == 100% since we adjusted to 9
983 #adjust the percentage to be == 100% since we adjusted to 9
984 if a_p > d_p:
984 if a_p > d_p:
985 a_p = a_p - (p_sum - width)
985 a_p = a_p - (p_sum - width)
986 else:
986 else:
987 d_p = d_p - (p_sum - width)
987 d_p = d_p - (p_sum - width)
988
988
989 a_v = a if a > 0 else ''
989 a_v = a if a > 0 else ''
990 d_v = d if d > 0 else ''
990 d_v = d if d > 0 else ''
991
991
992 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
992 d_a = '<div class="added %s" style="width:%s%%">%s</div>' % (
993 cgen('a', a_v, d_v), a_p, a_v
993 cgen('a', a_v, d_v), a_p, a_v
994 )
994 )
995 d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
995 d_d = '<div class="deleted %s" style="width:%s%%">%s</div>' % (
996 cgen('d', a_v, d_v), d_p, d_v
996 cgen('d', a_v, d_v), d_p, d_v
997 )
997 )
998 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
998 return literal('<div style="width:%spx">%s%s</div>' % (width, d_a, d_d))
999
999
1000
1000
1001 def urlify_text(text_, safe=True):
1001 def urlify_text(text_, safe=True):
1002 """
1002 """
1003 Extrac urls from text and make html links out of them
1003 Extrac urls from text and make html links out of them
1004
1004
1005 :param text_:
1005 :param text_:
1006 """
1006 """
1007
1007
1008 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
1008 url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]'''
1009 '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
1009 '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''')
1010
1010
1011 def url_func(match_obj):
1011 def url_func(match_obj):
1012 url_full = match_obj.groups()[0]
1012 url_full = match_obj.groups()[0]
1013 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
1013 return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full})
1014 _newtext = url_pat.sub(url_func, text_)
1014 _newtext = url_pat.sub(url_func, text_)
1015 if safe:
1015 if safe:
1016 return literal(_newtext)
1016 return literal(_newtext)
1017 return _newtext
1017 return _newtext
1018
1018
1019
1019
1020 def urlify_changesets(text_, repository):
1020 def urlify_changesets(text_, repository):
1021 """
1021 """
1022 Extract revision ids from changeset and make link from them
1022 Extract revision ids from changeset and make link from them
1023
1023
1024 :param text_:
1024 :param text_:
1025 :param repository: repo name to build the URL with
1025 :param repository: repo name to build the URL with
1026 """
1026 """
1027 from pylons import url # doh, we need to re-import url to mock it later
1027 from pylons import url # doh, we need to re-import url to mock it later
1028 URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)')
1028 URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)')
1029
1029
1030 def url_func(match_obj):
1030 def url_func(match_obj):
1031 rev = match_obj.groups()[1]
1031 rev = match_obj.groups()[1]
1032 pref = match_obj.groups()[0]
1032 pref = match_obj.groups()[0]
1033 suf = match_obj.groups()[2]
1033 suf = match_obj.groups()[2]
1034
1034
1035 tmpl = (
1035 tmpl = (
1036 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1036 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1037 '%(rev)s</a>%(suf)s'
1037 '%(rev)s</a>%(suf)s'
1038 )
1038 )
1039 return tmpl % {
1039 return tmpl % {
1040 'pref': pref,
1040 'pref': pref,
1041 'cls': 'revision-link',
1041 'cls': 'revision-link',
1042 'url': url('changeset_home', repo_name=repository, revision=rev),
1042 'url': url('changeset_home', repo_name=repository, revision=rev),
1043 'rev': rev,
1043 'rev': rev,
1044 'suf': suf
1044 'suf': suf
1045 }
1045 }
1046
1046
1047 newtext = URL_PAT.sub(url_func, text_)
1047 newtext = URL_PAT.sub(url_func, text_)
1048
1048
1049 return newtext
1049 return newtext
1050
1050
1051
1051
1052 def urlify_commit(text_, repository=None, link_=None):
1052 def urlify_commit(text_, repository=None, link_=None):
1053 """
1053 """
1054 Parses given text message and makes proper links.
1054 Parses given text message and makes proper links.
1055 issues are linked to given issue-server, and rest is a changeset link
1055 issues are linked to given issue-server, and rest is a changeset link
1056 if link_ is given, in other case it's a plain text
1056 if link_ is given, in other case it's a plain text
1057
1057
1058 :param text_:
1058 :param text_:
1059 :param repository:
1059 :param repository:
1060 :param link_: changeset link
1060 :param link_: changeset link
1061 """
1061 """
1062 import traceback
1062 import traceback
1063 from pylons import url # doh, we need to re-import url to mock it later
1063 from pylons import url # doh, we need to re-import url to mock it later
1064
1064
1065 def escaper(string):
1065 def escaper(string):
1066 return string.replace('<', '&lt;').replace('>', '&gt;')
1066 return string.replace('<', '&lt;').replace('>', '&gt;')
1067
1067
1068 def linkify_others(t, l):
1068 def linkify_others(t, l):
1069 urls = re.compile(r'(\<a.*?\<\/a\>)',)
1069 urls = re.compile(r'(\<a.*?\<\/a\>)',)
1070 links = []
1070 links = []
1071 for e in urls.split(t):
1071 for e in urls.split(t):
1072 if not urls.match(e):
1072 if not urls.match(e):
1073 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
1073 links.append('<a class="message-link" href="%s">%s</a>' % (l, e))
1074 else:
1074 else:
1075 links.append(e)
1075 links.append(e)
1076
1076
1077 return ''.join(links)
1077 return ''.join(links)
1078
1078
1079 # urlify changesets - extrac revisions and make link out of them
1079 # urlify changesets - extrac revisions and make link out of them
1080 newtext = urlify_changesets(escaper(text_), repository)
1080 newtext = urlify_changesets(escaper(text_), repository)
1081
1081
1082 # extract http/https links and make them real urls
1082 # extract http/https links and make them real urls
1083 newtext = urlify_text(newtext, safe=False)
1083 newtext = urlify_text(newtext, safe=False)
1084
1084
1085 try:
1085 try:
1086 from rhodecode import CONFIG
1086 from rhodecode import CONFIG
1087 conf = CONFIG
1087 conf = CONFIG
1088
1088
1089 # allow multiple issue servers to be used
1089 # allow multiple issue servers to be used
1090 valid_indices = [
1090 valid_indices = [
1091 x.group(1)
1091 x.group(1)
1092 for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
1092 for x in map(lambda x: re.match(r'issue_pat(.*)', x), conf.keys())
1093 if x and 'issue_server_link%s' % x.group(1) in conf
1093 if x and 'issue_server_link%s' % x.group(1) in conf
1094 and 'issue_prefix%s' % x.group(1) in conf
1094 and 'issue_prefix%s' % x.group(1) in conf
1095 ]
1095 ]
1096
1096
1097 log.debug('found issue server suffixes `%s` during valuation of: %s'
1097 log.debug('found issue server suffixes `%s` during valuation of: %s'
1098 % (','.join(valid_indices), newtext))
1098 % (','.join(valid_indices), newtext))
1099
1099
1100 for pattern_index in valid_indices:
1100 for pattern_index in valid_indices:
1101 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
1101 ISSUE_PATTERN = conf.get('issue_pat%s' % pattern_index)
1102 ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
1102 ISSUE_SERVER_LNK = conf.get('issue_server_link%s' % pattern_index)
1103 ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
1103 ISSUE_PREFIX = conf.get('issue_prefix%s' % pattern_index)
1104
1104
1105 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
1105 log.debug('pattern suffix `%s` PAT:%s SERVER_LINK:%s PREFIX:%s'
1106 % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
1106 % (pattern_index, ISSUE_PATTERN, ISSUE_SERVER_LNK,
1107 ISSUE_PREFIX))
1107 ISSUE_PREFIX))
1108
1108
1109 URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
1109 URL_PAT = re.compile(r'%s' % ISSUE_PATTERN)
1110
1110
1111 def url_func(match_obj):
1111 def url_func(match_obj):
1112 pref = ''
1112 pref = ''
1113 if match_obj.group().startswith(' '):
1113 if match_obj.group().startswith(' '):
1114 pref = ' '
1114 pref = ' '
1115
1115
1116 issue_id = ''.join(match_obj.groups())
1116 issue_id = ''.join(match_obj.groups())
1117 tmpl = (
1117 tmpl = (
1118 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1118 '%(pref)s<a class="%(cls)s" href="%(url)s">'
1119 '%(issue-prefix)s%(id-repr)s'
1119 '%(issue-prefix)s%(id-repr)s'
1120 '</a>'
1120 '</a>'
1121 )
1121 )
1122 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
1122 url = ISSUE_SERVER_LNK.replace('{id}', issue_id)
1123 if repository:
1123 if repository:
1124 url = url.replace('{repo}', repository)
1124 url = url.replace('{repo}', repository)
1125 repo_name = repository.split(URL_SEP)[-1]
1125 repo_name = repository.split(URL_SEP)[-1]
1126 url = url.replace('{repo_name}', repo_name)
1126 url = url.replace('{repo_name}', repo_name)
1127
1127
1128 return tmpl % {
1128 return tmpl % {
1129 'pref': pref,
1129 'pref': pref,
1130 'cls': 'issue-tracker-link',
1130 'cls': 'issue-tracker-link',
1131 'url': url,
1131 'url': url,
1132 'id-repr': issue_id,
1132 'id-repr': issue_id,
1133 'issue-prefix': ISSUE_PREFIX,
1133 'issue-prefix': ISSUE_PREFIX,
1134 'serv': ISSUE_SERVER_LNK,
1134 'serv': ISSUE_SERVER_LNK,
1135 }
1135 }
1136 newtext = URL_PAT.sub(url_func, newtext)
1136 newtext = URL_PAT.sub(url_func, newtext)
1137 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
1137 log.debug('processed prefix:`%s` => %s' % (pattern_index, newtext))
1138
1138
1139 # if we actually did something above
1139 # if we actually did something above
1140 if link_:
1140 if link_:
1141 # wrap not links into final link => link_
1141 # wrap not links into final link => link_
1142 newtext = linkify_others(newtext, link_)
1142 newtext = linkify_others(newtext, link_)
1143 except Exception:
1143 except Exception:
1144 log.error(traceback.format_exc())
1144 log.error(traceback.format_exc())
1145 pass
1145 pass
1146
1146
1147 return literal(newtext)
1147 return literal(newtext)
1148
1148
1149
1149
1150 def rst(source):
1150 def rst(source):
1151 return literal('<div class="rst-block">%s</div>' %
1151 return literal('<div class="rst-block">%s</div>' %
1152 MarkupRenderer.rst(source))
1152 MarkupRenderer.rst(source))
1153
1153
1154
1154
1155 def rst_w_mentions(source):
1155 def rst_w_mentions(source):
1156 """
1156 """
1157 Wrapped rst renderer with @mention highlighting
1157 Wrapped rst renderer with @mention highlighting
1158
1158
1159 :param source:
1159 :param source:
1160 """
1160 """
1161 return literal('<div class="rst-block">%s</div>' %
1161 return literal('<div class="rst-block">%s</div>' %
1162 MarkupRenderer.rst_with_mentions(source))
1162 MarkupRenderer.rst_with_mentions(source))
1163
1163
1164
1164
1165 def changeset_status(repo, revision):
1165 def changeset_status(repo, revision):
1166 return ChangesetStatusModel().get_status(repo, revision)
1166 return ChangesetStatusModel().get_status(repo, revision)
1167
1167
1168
1168
1169 def changeset_status_lbl(changeset_status):
1169 def changeset_status_lbl(changeset_status):
1170 return dict(ChangesetStatus.STATUSES).get(changeset_status)
1170 return dict(ChangesetStatus.STATUSES).get(changeset_status)
1171
1171
1172
1172
1173 def get_permission_name(key):
1173 def get_permission_name(key):
1174 return dict(Permission.PERMS).get(key)
1174 return dict(Permission.PERMS).get(key)
1175
1175
1176
1176
1177 def journal_filter_help():
1177 def journal_filter_help():
1178 return _(textwrap.dedent('''
1178 return _(textwrap.dedent('''
1179 Example filter terms:
1179 Example filter terms:
1180 repository:vcs
1180 repository:vcs
1181 username:marcin
1181 username:marcin
1182 action:*push*
1182 action:*push*
1183 ip:127.0.0.1
1183 ip:127.0.0.1
1184 date:20120101
1184 date:20120101
1185 date:[20120101100000 TO 20120102]
1185 date:[20120101100000 TO 20120102]
1186
1186
1187 Generate wildcards using '*' character:
1187 Generate wildcards using '*' character:
1188 "repositroy:vcs*" - search everything starting with 'vcs'
1188 "repositroy:vcs*" - search everything starting with 'vcs'
1189 "repository:*vcs*" - search for repository containing 'vcs'
1189 "repository:*vcs*" - search for repository containing 'vcs'
1190
1190
1191 Optional AND / OR operators in queries
1191 Optional AND / OR operators in queries
1192 "repository:vcs OR repository:test"
1192 "repository:vcs OR repository:test"
1193 "username:test AND repository:test*"
1193 "username:test AND repository:test*"
1194 '''))
1194 '''))
1195
1195
1196
1196
1197 def not_mapped_error(repo_name):
1197 def not_mapped_error(repo_name):
1198 flash(_('%s repository is not mapped to db perhaps'
1198 flash(_('%s repository is not mapped to db perhaps'
1199 ' it was created or renamed from the filesystem'
1199 ' it was created or renamed from the filesystem'
1200 ' please run the application again'
1200 ' please run the application again'
1201 ' in order to rescan repositories') % repo_name, category='error')
1201 ' in order to rescan repositories') % repo_name, category='error')
1202
1202
1203
1203
1204 def ip_range(ip_addr):
1204 def ip_range(ip_addr):
1205 from rhodecode.model.db import UserIpMap
1205 from rhodecode.model.db import UserIpMap
1206 s, e = UserIpMap._get_ip_range(ip_addr)
1206 s, e = UserIpMap._get_ip_range(ip_addr)
1207 return '%s - %s' % (s, e)
1207 return '%s - %s' % (s, e)
@@ -1,482 +1,482 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20 #email_prefix = [RhodeCode]
20 #email_prefix = [RhodeCode]
21
21
22 #smtp_server = mail.server.com
22 #smtp_server = mail.server.com
23 #smtp_username =
23 #smtp_username =
24 #smtp_password =
24 #smtp_password =
25 #smtp_port =
25 #smtp_port =
26 #smtp_use_tls = false
26 #smtp_use_tls = false
27 #smtp_use_ssl = true
27 #smtp_use_ssl = true
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
28 ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.)
29 #smtp_auth =
29 #smtp_auth =
30
30
31 [server:main]
31 [server:main]
32 ## PASTE
32 ## PASTE
33 ## nr of threads to spawn
33 ## nr of threads to spawn
34 #threadpool_workers = 5
34 #threadpool_workers = 5
35
35
36 ## max request before thread respawn
36 ## max request before thread respawn
37 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
38
38
39 ## option to use threads of process
39 ## option to use threads of process
40 #use_threadpool = true
40 #use_threadpool = true
41
41
42 #use = egg:Paste#http
42 #use = egg:Paste#http
43
43
44 ## WAITRESS
44 ## WAITRESS
45 threads = 5
45 threads = 5
46 ## 100GB
46 ## 100GB
47 max_request_body_size = 107374182400
47 max_request_body_size = 107374182400
48 use = egg:waitress#main
48 use = egg:waitress#main
49
49
50 host = 127.0.0.1
50 host = 127.0.0.1
51 port = 5000
51 port = 5000
52
52
53 ## prefix middleware for rc
53 ## prefix middleware for rc
54 #[filter:proxy-prefix]
54 #[filter:proxy-prefix]
55 #use = egg:PasteDeploy#prefix
55 #use = egg:PasteDeploy#prefix
56 #prefix = /<your-prefix>
56 #prefix = /<your-prefix>
57
57
58 [app:main]
58 [app:main]
59 use = egg:rhodecode
59 use = egg:rhodecode
60 ## enable proxy prefix middleware
60 ## enable proxy prefix middleware
61 #filter-with = proxy-prefix
61 #filter-with = proxy-prefix
62
62
63 full_stack = true
63 full_stack = true
64 static_files = true
64 static_files = true
65 ## Optional Languages
65 ## Optional Languages
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
66 ## en, fr, ja, pt_BR, zh_CN, zh_TW, pl
67 lang = en
67 lang = en
68 cache_dir = /tmp/rc/data
68 cache_dir = /tmp/rc/data
69 index_dir = /tmp/rc/index
69 index_dir = /tmp/rc/index
70
70
71 ## uncomment and set this path to use archive download cache
71 ## uncomment and set this path to use archive download cache
72 #archive_cache_dir = /tmp/tarballcache
72 #archive_cache_dir = /tmp/tarballcache
73
73
74 ## change this to unique ID for security
74 ## change this to unique ID for security
75 app_instance_uuid = rc-production
75 app_instance_uuid = rc-production
76
76
77 ## cut off limit for large diffs (size in bytes)
77 ## cut off limit for large diffs (size in bytes)
78 cut_off_limit = 256000
78 cut_off_limit = 256000
79
79
80 ## use cache version of scm repo everywhere
80 ## use cache version of scm repo everywhere
81 vcs_full_cache = false
81 vcs_full_cache = false
82
82
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
83 ## force https in RhodeCode, fixes https redirects, assumes it's always https
84 force_https = false
84 force_https = false
85
85
86 ## use Strict-Transport-Security headers
86 ## use Strict-Transport-Security headers
87 use_htsts = false
87 use_htsts = false
88
88
89 ## number of commits stats will parse on each iteration
89 ## number of commits stats will parse on each iteration
90 commit_parse_limit = 25
90 commit_parse_limit = 25
91
91
92 ## number of items displayed in lightweight dashboard before paginating is shown
92 ## number of items displayed in lightweight dashboard before paginating is shown
93 dashboard_items = 100
93 dashboard_items = 100
94
94
95 ## use gravatar service to display avatars
95 ## use gravatar service to display avatars
96 use_gravatar = true
96 use_gravatar = true
97
97
98 ## path to git executable
98 ## path to git executable
99 git_path = git
99 git_path = git
100
100
101 ## git rev filter option, --all is the default filter, if you need to
101 ## git rev filter option, --all is the default filter, if you need to
102 ## hide all refs in changelog switch this to --branches --tags
102 ## hide all refs in changelog switch this to --branches --tags
103 git_rev_filter=--all
103 git_rev_filter=--all
104
104
105 ## RSS feed options
105 ## RSS feed options
106 rss_cut_off_limit = 256000
106 rss_cut_off_limit = 256000
107 rss_items_per_page = 10
107 rss_items_per_page = 10
108 rss_include_diff = false
108 rss_include_diff = false
109
109
110 ## show hash options for changelog
110 ## options for showing and identifying changesets
111 sha_len = 12
111 show_sha_length = 12
112 sha_show_numeric_rev = true
112 show_revision_number = true
113
113
114
114
115 ## alternative_gravatar_url allows you to use your own avatar server application
115 ## alternative_gravatar_url allows you to use your own avatar server application
116 ## the following parts of the URL will be replaced
116 ## the following parts of the URL will be replaced
117 ## {email} user email
117 ## {email} user email
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
118 ## {md5email} md5 hash of the user email (like at gravatar.com)
119 ## {size} size of the image that is expected from the server application
119 ## {size} size of the image that is expected from the server application
120 ## {scheme} http/https from RhodeCode server
120 ## {scheme} http/https from RhodeCode server
121 ## {netloc} network location from RhodeCode server
121 ## {netloc} network location from RhodeCode server
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
122 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
123 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
124
124
125
125
126 ## container auth options
126 ## container auth options
127 container_auth_enabled = false
127 container_auth_enabled = false
128 proxypass_auth_enabled = false
128 proxypass_auth_enabled = false
129
129
130 ## default encoding used to convert from and to unicode
130 ## default encoding used to convert from and to unicode
131 ## can be also a comma seperated list of encoding in case of mixed encodings
131 ## can be also a comma seperated list of encoding in case of mixed encodings
132 default_encoding = utf8
132 default_encoding = utf8
133
133
134 ## overwrite schema of clone url
134 ## overwrite schema of clone url
135 ## available vars:
135 ## available vars:
136 ## scheme - http/https
136 ## scheme - http/https
137 ## user - current user
137 ## user - current user
138 ## pass - password
138 ## pass - password
139 ## netloc - network location
139 ## netloc - network location
140 ## path - usually repo_name
140 ## path - usually repo_name
141
141
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
142 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
143
143
144 ## issue tracking mapping for commits messages
144 ## issue tracking mapping for commits messages
145 ## comment out issue_pat, issue_server, issue_prefix to enable
145 ## comment out issue_pat, issue_server, issue_prefix to enable
146
146
147 ## pattern to get the issues from commit messages
147 ## pattern to get the issues from commit messages
148 ## default one used here is #<numbers> with a regex passive group for `#`
148 ## default one used here is #<numbers> with a regex passive group for `#`
149 ## {id} will be all groups matched from this pattern
149 ## {id} will be all groups matched from this pattern
150
150
151 issue_pat = (?:\s*#)(\d+)
151 issue_pat = (?:\s*#)(\d+)
152
152
153 ## server url to the issue, each {id} will be replaced with match
153 ## server url to the issue, each {id} will be replaced with match
154 ## fetched from the regex and {repo} is replaced with full repository name
154 ## fetched from the regex and {repo} is replaced with full repository name
155 ## including groups {repo_name} is replaced with just name of repo
155 ## including groups {repo_name} is replaced with just name of repo
156
156
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
157 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
158
158
159 ## prefix to add to link to indicate it's an url
159 ## prefix to add to link to indicate it's an url
160 ## #314 will be replaced by <issue_prefix><id>
160 ## #314 will be replaced by <issue_prefix><id>
161
161
162 issue_prefix = #
162 issue_prefix = #
163
163
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
164 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
165 ## multiple patterns, to other issues server, wiki or others
165 ## multiple patterns, to other issues server, wiki or others
166 ## below an example how to create a wiki pattern
166 ## below an example how to create a wiki pattern
167 # #wiki-some-id -> https://mywiki.com/some-id
167 # #wiki-some-id -> https://mywiki.com/some-id
168
168
169 #issue_pat_wiki = (?:wiki-)(.+)
169 #issue_pat_wiki = (?:wiki-)(.+)
170 #issue_server_link_wiki = https://mywiki.com/{id}
170 #issue_server_link_wiki = https://mywiki.com/{id}
171 #issue_prefix_wiki = WIKI-
171 #issue_prefix_wiki = WIKI-
172
172
173
173
174 ## instance-id prefix
174 ## instance-id prefix
175 ## a prefix key for this instance used for cache invalidation when running
175 ## a prefix key for this instance used for cache invalidation when running
176 ## multiple instances of rhodecode, make sure it's globally unique for
176 ## multiple instances of rhodecode, make sure it's globally unique for
177 ## all running rhodecode instances. Leave empty if you don't use it
177 ## all running rhodecode instances. Leave empty if you don't use it
178 instance_id =
178 instance_id =
179
179
180 ## alternative return HTTP header for failed authentication. Default HTTP
180 ## alternative return HTTP header for failed authentication. Default HTTP
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
181 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
182 ## handling that. Set this variable to 403 to return HTTPForbidden
182 ## handling that. Set this variable to 403 to return HTTPForbidden
183 auth_ret_code =
183 auth_ret_code =
184
184
185 ## locking return code. When repository is locked return this HTTP code. 2XX
185 ## locking return code. When repository is locked return this HTTP code. 2XX
186 ## codes don't break the transactions while 4XX codes do
186 ## codes don't break the transactions while 4XX codes do
187 lock_ret_code = 423
187 lock_ret_code = 423
188
188
189
189
190 ####################################
190 ####################################
191 ### CELERY CONFIG ####
191 ### CELERY CONFIG ####
192 ####################################
192 ####################################
193 use_celery = false
193 use_celery = false
194 broker.host = localhost
194 broker.host = localhost
195 broker.vhost = rabbitmqhost
195 broker.vhost = rabbitmqhost
196 broker.port = 5672
196 broker.port = 5672
197 broker.user = rabbitmq
197 broker.user = rabbitmq
198 broker.password = qweqwe
198 broker.password = qweqwe
199
199
200 celery.imports = rhodecode.lib.celerylib.tasks
200 celery.imports = rhodecode.lib.celerylib.tasks
201
201
202 celery.result.backend = amqp
202 celery.result.backend = amqp
203 celery.result.dburi = amqp://
203 celery.result.dburi = amqp://
204 celery.result.serialier = json
204 celery.result.serialier = json
205
205
206 #celery.send.task.error.emails = true
206 #celery.send.task.error.emails = true
207 #celery.amqp.task.result.expires = 18000
207 #celery.amqp.task.result.expires = 18000
208
208
209 celeryd.concurrency = 2
209 celeryd.concurrency = 2
210 #celeryd.log.file = celeryd.log
210 #celeryd.log.file = celeryd.log
211 celeryd.log.level = debug
211 celeryd.log.level = debug
212 celeryd.max.tasks.per.child = 1
212 celeryd.max.tasks.per.child = 1
213
213
214 ## tasks will never be sent to the queue, but executed locally instead.
214 ## tasks will never be sent to the queue, but executed locally instead.
215 celery.always.eager = false
215 celery.always.eager = false
216
216
217 ####################################
217 ####################################
218 ### BEAKER CACHE ####
218 ### BEAKER CACHE ####
219 ####################################
219 ####################################
220 beaker.cache.data_dir=/tmp/rc/data/cache/data
220 beaker.cache.data_dir=/tmp/rc/data/cache/data
221 beaker.cache.lock_dir=/tmp/rc/data/cache/lock
221 beaker.cache.lock_dir=/tmp/rc/data/cache/lock
222
222
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
223 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
224
224
225 beaker.cache.super_short_term.type=memory
225 beaker.cache.super_short_term.type=memory
226 beaker.cache.super_short_term.expire=1
226 beaker.cache.super_short_term.expire=1
227 beaker.cache.super_short_term.key_length = 256
227 beaker.cache.super_short_term.key_length = 256
228
228
229 beaker.cache.short_term.type=memory
229 beaker.cache.short_term.type=memory
230 beaker.cache.short_term.expire=60
230 beaker.cache.short_term.expire=60
231 beaker.cache.short_term.key_length = 256
231 beaker.cache.short_term.key_length = 256
232
232
233 beaker.cache.long_term.type=memory
233 beaker.cache.long_term.type=memory
234 beaker.cache.long_term.expire=36000
234 beaker.cache.long_term.expire=36000
235 beaker.cache.long_term.key_length = 256
235 beaker.cache.long_term.key_length = 256
236
236
237 beaker.cache.sql_cache_short.type=memory
237 beaker.cache.sql_cache_short.type=memory
238 beaker.cache.sql_cache_short.expire=1
238 beaker.cache.sql_cache_short.expire=1
239 beaker.cache.sql_cache_short.key_length = 256
239 beaker.cache.sql_cache_short.key_length = 256
240
240
241 beaker.cache.sql_cache_med.type=memory
241 beaker.cache.sql_cache_med.type=memory
242 beaker.cache.sql_cache_med.expire=360
242 beaker.cache.sql_cache_med.expire=360
243 beaker.cache.sql_cache_med.key_length = 256
243 beaker.cache.sql_cache_med.key_length = 256
244
244
245 beaker.cache.sql_cache_long.type=file
245 beaker.cache.sql_cache_long.type=file
246 beaker.cache.sql_cache_long.expire=3600
246 beaker.cache.sql_cache_long.expire=3600
247 beaker.cache.sql_cache_long.key_length = 256
247 beaker.cache.sql_cache_long.key_length = 256
248
248
249 ####################################
249 ####################################
250 ### BEAKER SESSION ####
250 ### BEAKER SESSION ####
251 ####################################
251 ####################################
252 ## Type of storage used for the session, current types are
252 ## Type of storage used for the session, current types are
253 ## dbm, file, memcached, database, and memory.
253 ## dbm, file, memcached, database, and memory.
254 ## The storage uses the Container API
254 ## The storage uses the Container API
255 ## that is also used by the cache system.
255 ## that is also used by the cache system.
256
256
257 ## db session ##
257 ## db session ##
258 #beaker.session.type = ext:database
258 #beaker.session.type = ext:database
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
259 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
260 #beaker.session.table_name = db_session
260 #beaker.session.table_name = db_session
261
261
262 ## encrypted cookie client side session, good for many instances ##
262 ## encrypted cookie client side session, good for many instances ##
263 #beaker.session.type = cookie
263 #beaker.session.type = cookie
264
264
265 ## file based cookies (default) ##
265 ## file based cookies (default) ##
266 #beaker.session.type = file
266 #beaker.session.type = file
267
267
268
268
269 beaker.session.key = rhodecode
269 beaker.session.key = rhodecode
270 ## secure cookie requires AES python libraries
270 ## secure cookie requires AES python libraries
271 #beaker.session.encrypt_key = <key_for_encryption>
271 #beaker.session.encrypt_key = <key_for_encryption>
272 #beaker.session.validate_key = <validation_key>
272 #beaker.session.validate_key = <validation_key>
273
273
274 ## sets session as invalid if it haven't been accessed for given amount of time
274 ## sets session as invalid if it haven't been accessed for given amount of time
275 beaker.session.timeout = 3600
275 beaker.session.timeout = 3600
276 beaker.session.httponly = true
276 beaker.session.httponly = true
277 #beaker.session.cookie_path = /<your-prefix>
277 #beaker.session.cookie_path = /<your-prefix>
278
278
279 ## uncomment for https secure cookie
279 ## uncomment for https secure cookie
280 beaker.session.secure = false
280 beaker.session.secure = false
281
281
282 ## auto save the session to not to use .save()
282 ## auto save the session to not to use .save()
283 beaker.session.auto = False
283 beaker.session.auto = False
284
284
285 ## default cookie expiration time in seconds `true` expire at browser close ##
285 ## default cookie expiration time in seconds `true` expire at browser close ##
286 #beaker.session.cookie_expires = 3600
286 #beaker.session.cookie_expires = 3600
287
287
288
288
289 ############################
289 ############################
290 ## ERROR HANDLING SYSTEMS ##
290 ## ERROR HANDLING SYSTEMS ##
291 ############################
291 ############################
292
292
293 ####################
293 ####################
294 ### [errormator] ###
294 ### [errormator] ###
295 ####################
295 ####################
296
296
297 ## Errormator is tailored to work with RhodeCode, see
297 ## Errormator is tailored to work with RhodeCode, see
298 ## http://errormator.com for details how to obtain an account
298 ## http://errormator.com for details how to obtain an account
299 ## you must install python package `errormator_client` to make it work
299 ## you must install python package `errormator_client` to make it work
300
300
301 ## errormator enabled
301 ## errormator enabled
302 errormator = false
302 errormator = false
303
303
304 errormator.server_url = https://api.errormator.com
304 errormator.server_url = https://api.errormator.com
305 errormator.api_key = YOUR_API_KEY
305 errormator.api_key = YOUR_API_KEY
306
306
307 ## TWEAK AMOUNT OF INFO SENT HERE
307 ## TWEAK AMOUNT OF INFO SENT HERE
308
308
309 ## enables 404 error logging (default False)
309 ## enables 404 error logging (default False)
310 errormator.report_404 = false
310 errormator.report_404 = false
311
311
312 ## time in seconds after request is considered being slow (default 1)
312 ## time in seconds after request is considered being slow (default 1)
313 errormator.slow_request_time = 1
313 errormator.slow_request_time = 1
314
314
315 ## record slow requests in application
315 ## record slow requests in application
316 ## (needs to be enabled for slow datastore recording and time tracking)
316 ## (needs to be enabled for slow datastore recording and time tracking)
317 errormator.slow_requests = true
317 errormator.slow_requests = true
318
318
319 ## enable hooking to application loggers
319 ## enable hooking to application loggers
320 # errormator.logging = true
320 # errormator.logging = true
321
321
322 ## minimum log level for log capture
322 ## minimum log level for log capture
323 # errormator.logging.level = WARNING
323 # errormator.logging.level = WARNING
324
324
325 ## send logs only from erroneous/slow requests
325 ## send logs only from erroneous/slow requests
326 ## (saves API quota for intensive logging)
326 ## (saves API quota for intensive logging)
327 errormator.logging_on_error = false
327 errormator.logging_on_error = false
328
328
329 ## list of additonal keywords that should be grabbed from environ object
329 ## list of additonal keywords that should be grabbed from environ object
330 ## can be string with comma separated list of words in lowercase
330 ## can be string with comma separated list of words in lowercase
331 ## (by default client will always send following info:
331 ## (by default client will always send following info:
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
332 ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
333 ## start with HTTP* this list be extended with additional keywords here
333 ## start with HTTP* this list be extended with additional keywords here
334 errormator.environ_keys_whitelist =
334 errormator.environ_keys_whitelist =
335
335
336
336
337 ## list of keywords that should be blanked from request object
337 ## list of keywords that should be blanked from request object
338 ## can be string with comma separated list of words in lowercase
338 ## can be string with comma separated list of words in lowercase
339 ## (by default client will always blank keys that contain following words
339 ## (by default client will always blank keys that contain following words
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
340 ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
341 ## this list be extended with additional keywords set here
341 ## this list be extended with additional keywords set here
342 errormator.request_keys_blacklist =
342 errormator.request_keys_blacklist =
343
343
344
344
345 ## list of namespaces that should be ignores when gathering log entries
345 ## list of namespaces that should be ignores when gathering log entries
346 ## can be string with comma separated list of namespaces
346 ## can be string with comma separated list of namespaces
347 ## (by default the client ignores own entries: errormator_client.client)
347 ## (by default the client ignores own entries: errormator_client.client)
348 errormator.log_namespace_blacklist =
348 errormator.log_namespace_blacklist =
349
349
350
350
351 ################
351 ################
352 ### [sentry] ###
352 ### [sentry] ###
353 ################
353 ################
354
354
355 ## sentry is a alternative open source error aggregator
355 ## sentry is a alternative open source error aggregator
356 ## you must install python packages `sentry` and `raven` to enable
356 ## you must install python packages `sentry` and `raven` to enable
357
357
358 sentry.dsn = YOUR_DNS
358 sentry.dsn = YOUR_DNS
359 sentry.servers =
359 sentry.servers =
360 sentry.name =
360 sentry.name =
361 sentry.key =
361 sentry.key =
362 sentry.public_key =
362 sentry.public_key =
363 sentry.secret_key =
363 sentry.secret_key =
364 sentry.project =
364 sentry.project =
365 sentry.site =
365 sentry.site =
366 sentry.include_paths =
366 sentry.include_paths =
367 sentry.exclude_paths =
367 sentry.exclude_paths =
368
368
369
369
370 ################################################################################
370 ################################################################################
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
371 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
372 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
373 ## execute malicious code after an exception is raised. ##
373 ## execute malicious code after an exception is raised. ##
374 ################################################################################
374 ################################################################################
375 set debug = false
375 set debug = false
376
376
377 ##################################
377 ##################################
378 ### LOGVIEW CONFIG ###
378 ### LOGVIEW CONFIG ###
379 ##################################
379 ##################################
380 logview.sqlalchemy = #faa
380 logview.sqlalchemy = #faa
381 logview.pylons.templating = #bfb
381 logview.pylons.templating = #bfb
382 logview.pylons.util = #eee
382 logview.pylons.util = #eee
383
383
384 #########################################################
384 #########################################################
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
385 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
386 #########################################################
386 #########################################################
387 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.sqlite
387 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode_test.sqlite
388 #sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode_test
388 #sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode_test
389 #sqlalchemy.db1.url = mysql://root:qwe@localhost/rhodecode_test
389 #sqlalchemy.db1.url = mysql://root:qwe@localhost/rhodecode_test
390 sqlalchemy.db1.echo = false
390 sqlalchemy.db1.echo = false
391 sqlalchemy.db1.pool_recycle = 3600
391 sqlalchemy.db1.pool_recycle = 3600
392 sqlalchemy.db1.convert_unicode = true
392 sqlalchemy.db1.convert_unicode = true
393
393
394 ################################
394 ################################
395 ### LOGGING CONFIGURATION ####
395 ### LOGGING CONFIGURATION ####
396 ################################
396 ################################
397 [loggers]
397 [loggers]
398 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
398 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
399
399
400 [handlers]
400 [handlers]
401 keys = console, console_sql
401 keys = console, console_sql
402
402
403 [formatters]
403 [formatters]
404 keys = generic, color_formatter, color_formatter_sql
404 keys = generic, color_formatter, color_formatter_sql
405
405
406 #############
406 #############
407 ## LOGGERS ##
407 ## LOGGERS ##
408 #############
408 #############
409 [logger_root]
409 [logger_root]
410 level = DEBUG
410 level = DEBUG
411 handlers = console
411 handlers = console
412
412
413 [logger_routes]
413 [logger_routes]
414 level = DEBUG
414 level = DEBUG
415 handlers =
415 handlers =
416 qualname = routes.middleware
416 qualname = routes.middleware
417 ## "level = DEBUG" logs the route matched and routing variables.
417 ## "level = DEBUG" logs the route matched and routing variables.
418 propagate = 1
418 propagate = 1
419
419
420 [logger_beaker]
420 [logger_beaker]
421 level = DEBUG
421 level = DEBUG
422 handlers =
422 handlers =
423 qualname = beaker.container
423 qualname = beaker.container
424 propagate = 1
424 propagate = 1
425
425
426 [logger_templates]
426 [logger_templates]
427 level = INFO
427 level = INFO
428 handlers =
428 handlers =
429 qualname = pylons.templating
429 qualname = pylons.templating
430 propagate = 1
430 propagate = 1
431
431
432 [logger_rhodecode]
432 [logger_rhodecode]
433 level = DEBUG
433 level = DEBUG
434 handlers =
434 handlers =
435 qualname = rhodecode
435 qualname = rhodecode
436 propagate = 1
436 propagate = 1
437
437
438 [logger_sqlalchemy]
438 [logger_sqlalchemy]
439 level = ERROR
439 level = ERROR
440 handlers = console
440 handlers = console
441 qualname = sqlalchemy.engine
441 qualname = sqlalchemy.engine
442 propagate = 0
442 propagate = 0
443
443
444 [logger_whoosh_indexer]
444 [logger_whoosh_indexer]
445 level = DEBUG
445 level = DEBUG
446 handlers =
446 handlers =
447 qualname = whoosh_indexer
447 qualname = whoosh_indexer
448 propagate = 1
448 propagate = 1
449
449
450 ##############
450 ##############
451 ## HANDLERS ##
451 ## HANDLERS ##
452 ##############
452 ##############
453
453
454 [handler_console]
454 [handler_console]
455 class = StreamHandler
455 class = StreamHandler
456 args = (sys.stderr,)
456 args = (sys.stderr,)
457 level = NOTSET
457 level = NOTSET
458 formatter = generic
458 formatter = generic
459
459
460 [handler_console_sql]
460 [handler_console_sql]
461 class = StreamHandler
461 class = StreamHandler
462 args = (sys.stderr,)
462 args = (sys.stderr,)
463 level = WARN
463 level = WARN
464 formatter = generic
464 formatter = generic
465
465
466 ################
466 ################
467 ## FORMATTERS ##
467 ## FORMATTERS ##
468 ################
468 ################
469
469
470 [formatter_generic]
470 [formatter_generic]
471 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
471 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
472 datefmt = %Y-%m-%d %H:%M:%S
472 datefmt = %Y-%m-%d %H:%M:%S
473
473
474 [formatter_color_formatter]
474 [formatter_color_formatter]
475 class=rhodecode.lib.colored_formatter.ColorFormatter
475 class=rhodecode.lib.colored_formatter.ColorFormatter
476 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
476 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
477 datefmt = %Y-%m-%d %H:%M:%S
477 datefmt = %Y-%m-%d %H:%M:%S
478
478
479 [formatter_color_formatter_sql]
479 [formatter_color_formatter_sql]
480 class=rhodecode.lib.colored_formatter.ColorFormatterSql
480 class=rhodecode.lib.colored_formatter.ColorFormatterSql
481 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
481 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
482 datefmt = %Y-%m-%d %H:%M:%S
482 datefmt = %Y-%m-%d %H:%M:%S
General Comments 0
You need to be logged in to leave comments. Login now