##// END OF EJS Templates
added option to ini file to define lightweight dashboard items per page before pagination
marcink -
r3087:a797ada9 beta
parent child Browse files
Show More
@@ -1,432 +1,439 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 ##nr of threads to spawn
33 ##nr of threads to spawn
33 #threadpool_workers = 5
34 #threadpool_workers = 5
34
35
35 ##max request before thread respawn
36 ##max request before thread respawn
36 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
37
38
38 ##option to use threads of process
39 ##option to use threads of process
39 #use_threadpool = true
40 #use_threadpool = true
40
41
41 #use = egg:Paste#http
42 #use = egg:Paste#http
43
44 #WAITRESS
45 threads = 5
42 use = egg:waitress#main
46 use = egg:waitress#main
47
43 host = 0.0.0.0
48 host = 0.0.0.0
44 port = 5000
49 port = 5000
45
50
46 [filter:proxy-prefix]
51 [filter:proxy-prefix]
47 # prefix middleware for rc
52 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
53 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
54 prefix = /<your-prefix>
50
55
51 [app:main]
56 [app:main]
52 use = egg:rhodecode
57 use = egg:rhodecode
53 #filter-with = proxy-prefix
58 #filter-with = proxy-prefix
54 full_stack = true
59 full_stack = true
55 static_files = true
60 static_files = true
56 # Optional Languages
61 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
62 # en, fr, ja, pt_BR, zh_CN, zh_TW, pl
58 lang = en
63 lang = en
59 cache_dir = %(here)s/data
64 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
65 index_dir = %(here)s/data/index
61 app_instance_uuid = rc-develop
66 app_instance_uuid = rc-develop
62 cut_off_limit = 256000
67 cut_off_limit = 256000
63 vcs_full_cache = True
68 vcs_full_cache = True
64 force_https = false
69 force_https = false
65 commit_parse_limit = 25
70 commit_parse_limit = 25
71 # number of items displayed in lightweight dashboard before paginating
72 dashboard_items = 100
66 use_gravatar = true
73 use_gravatar = true
67
74
68 ## RSS feed options
75 ## RSS feed options
69
76
70 rss_cut_off_limit = 256000
77 rss_cut_off_limit = 256000
71 rss_items_per_page = 10
78 rss_items_per_page = 10
72 rss_include_diff = false
79 rss_include_diff = false
73
80
74
81
75 ## alternative_gravatar_url allows you to use your own avatar server application
82 ## alternative_gravatar_url allows you to use your own avatar server application
76 ## the following parts of the URL will be replaced
83 ## the following parts of the URL will be replaced
77 ## {email} user email
84 ## {email} user email
78 ## {md5email} md5 hash of the user email (like at gravatar.com)
85 ## {md5email} md5 hash of the user email (like at gravatar.com)
79 ## {size} size of the image that is expected from the server application
86 ## {size} size of the image that is expected from the server application
80 ## {scheme} http/https from RhodeCode server
87 ## {scheme} http/https from RhodeCode server
81 ## {netloc} network location from RhodeCode server
88 ## {netloc} network location from RhodeCode server
82 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
89 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
83 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
90 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
84
91
85 container_auth_enabled = false
92 container_auth_enabled = false
86 proxypass_auth_enabled = false
93 proxypass_auth_enabled = false
87 ## default encoding used to convert from and to unicode
94 ## default encoding used to convert from and to unicode
88 ## can be also a comma seperated list of encoding in case of mixed encodings
95 ## can be also a comma seperated list of encoding in case of mixed encodings
89 default_encoding = utf8
96 default_encoding = utf8
90
97
91 ## overwrite schema of clone url
98 ## overwrite schema of clone url
92 ## available vars:
99 ## available vars:
93 ## scheme - http/https
100 ## scheme - http/https
94 ## user - current user
101 ## user - current user
95 ## pass - password
102 ## pass - password
96 ## netloc - network location
103 ## netloc - network location
97 ## path - usually repo_name
104 ## path - usually repo_name
98
105
99 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
106 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
100
107
101 ## issue tracking mapping for commits messages
108 ## issue tracking mapping for commits messages
102 ## comment out issue_pat, issue_server, issue_prefix to enable
109 ## comment out issue_pat, issue_server, issue_prefix to enable
103
110
104 ## pattern to get the issues from commit messages
111 ## pattern to get the issues from commit messages
105 ## default one used here is #<numbers> with a regex passive group for `#`
112 ## default one used here is #<numbers> with a regex passive group for `#`
106 ## {id} will be all groups matched from this pattern
113 ## {id} will be all groups matched from this pattern
107
114
108 issue_pat = (?:\s*#)(\d+)
115 issue_pat = (?:\s*#)(\d+)
109
116
110 ## server url to the issue, each {id} will be replaced with match
117 ## server url to the issue, each {id} will be replaced with match
111 ## fetched from the regex and {repo} is replaced with full repository name
118 ## fetched from the regex and {repo} is replaced with full repository name
112 ## including groups {repo_name} is replaced with just name of repo
119 ## including groups {repo_name} is replaced with just name of repo
113
120
114 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
121 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
115
122
116 ## prefix to add to link to indicate it's an url
123 ## prefix to add to link to indicate it's an url
117 ## #314 will be replaced by <issue_prefix><id>
124 ## #314 will be replaced by <issue_prefix><id>
118
125
119 issue_prefix = #
126 issue_prefix = #
120
127
121 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
128 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
122 ## multiple patterns, to other issues server, wiki or others
129 ## multiple patterns, to other issues server, wiki or others
123 ## below an example how to create a wiki pattern
130 ## below an example how to create a wiki pattern
124 # #wiki-some-id -> https://mywiki.com/some-id
131 # #wiki-some-id -> https://mywiki.com/some-id
125
132
126 #issue_pat_wiki = (?:wiki-)(.+)
133 #issue_pat_wiki = (?:wiki-)(.+)
127 #issue_server_link_wiki = https://mywiki.com/{id}
134 #issue_server_link_wiki = https://mywiki.com/{id}
128 #issue_prefix_wiki = WIKI-
135 #issue_prefix_wiki = WIKI-
129
136
130
137
131 ## instance-id prefix
138 ## instance-id prefix
132 ## a prefix key for this instance used for cache invalidation when running
139 ## a prefix key for this instance used for cache invalidation when running
133 ## multiple instances of rhodecode, make sure it's globally unique for
140 ## multiple instances of rhodecode, make sure it's globally unique for
134 ## all running rhodecode instances. Leave empty if you don't use it
141 ## all running rhodecode instances. Leave empty if you don't use it
135 instance_id =
142 instance_id =
136
143
137 ## alternative return HTTP header for failed authentication. Default HTTP
144 ## alternative return HTTP header for failed authentication. Default HTTP
138 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
145 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
139 ## handling that. Set this variable to 403 to return HTTPForbidden
146 ## handling that. Set this variable to 403 to return HTTPForbidden
140 auth_ret_code =
147 auth_ret_code =
141
148
142 ####################################
149 ####################################
143 ### CELERY CONFIG ####
150 ### CELERY CONFIG ####
144 ####################################
151 ####################################
145 use_celery = false
152 use_celery = false
146 broker.host = localhost
153 broker.host = localhost
147 broker.vhost = rabbitmqhost
154 broker.vhost = rabbitmqhost
148 broker.port = 5672
155 broker.port = 5672
149 broker.user = rabbitmq
156 broker.user = rabbitmq
150 broker.password = qweqwe
157 broker.password = qweqwe
151
158
152 celery.imports = rhodecode.lib.celerylib.tasks
159 celery.imports = rhodecode.lib.celerylib.tasks
153
160
154 celery.result.backend = amqp
161 celery.result.backend = amqp
155 celery.result.dburi = amqp://
162 celery.result.dburi = amqp://
156 celery.result.serialier = json
163 celery.result.serialier = json
157
164
158 #celery.send.task.error.emails = true
165 #celery.send.task.error.emails = true
159 #celery.amqp.task.result.expires = 18000
166 #celery.amqp.task.result.expires = 18000
160
167
161 celeryd.concurrency = 2
168 celeryd.concurrency = 2
162 #celeryd.log.file = celeryd.log
169 #celeryd.log.file = celeryd.log
163 celeryd.log.level = debug
170 celeryd.log.level = debug
164 celeryd.max.tasks.per.child = 1
171 celeryd.max.tasks.per.child = 1
165
172
166 #tasks will never be sent to the queue, but executed locally instead.
173 #tasks will never be sent to the queue, but executed locally instead.
167 celery.always.eager = false
174 celery.always.eager = false
168
175
169 ####################################
176 ####################################
170 ### BEAKER CACHE ####
177 ### BEAKER CACHE ####
171 ####################################
178 ####################################
172 beaker.cache.data_dir=%(here)s/data/cache/data
179 beaker.cache.data_dir=%(here)s/data/cache/data
173 beaker.cache.lock_dir=%(here)s/data/cache/lock
180 beaker.cache.lock_dir=%(here)s/data/cache/lock
174
181
175 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
182 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
176
183
177 beaker.cache.super_short_term.type=memory
184 beaker.cache.super_short_term.type=memory
178 beaker.cache.super_short_term.expire=10
185 beaker.cache.super_short_term.expire=10
179 beaker.cache.super_short_term.key_length = 256
186 beaker.cache.super_short_term.key_length = 256
180
187
181 beaker.cache.short_term.type=memory
188 beaker.cache.short_term.type=memory
182 beaker.cache.short_term.expire=60
189 beaker.cache.short_term.expire=60
183 beaker.cache.short_term.key_length = 256
190 beaker.cache.short_term.key_length = 256
184
191
185 beaker.cache.long_term.type=memory
192 beaker.cache.long_term.type=memory
186 beaker.cache.long_term.expire=36000
193 beaker.cache.long_term.expire=36000
187 beaker.cache.long_term.key_length = 256
194 beaker.cache.long_term.key_length = 256
188
195
189 beaker.cache.sql_cache_short.type=memory
196 beaker.cache.sql_cache_short.type=memory
190 beaker.cache.sql_cache_short.expire=10
197 beaker.cache.sql_cache_short.expire=10
191 beaker.cache.sql_cache_short.key_length = 256
198 beaker.cache.sql_cache_short.key_length = 256
192
199
193 beaker.cache.sql_cache_med.type=memory
200 beaker.cache.sql_cache_med.type=memory
194 beaker.cache.sql_cache_med.expire=360
201 beaker.cache.sql_cache_med.expire=360
195 beaker.cache.sql_cache_med.key_length = 256
202 beaker.cache.sql_cache_med.key_length = 256
196
203
197 beaker.cache.sql_cache_long.type=file
204 beaker.cache.sql_cache_long.type=file
198 beaker.cache.sql_cache_long.expire=3600
205 beaker.cache.sql_cache_long.expire=3600
199 beaker.cache.sql_cache_long.key_length = 256
206 beaker.cache.sql_cache_long.key_length = 256
200
207
201 ####################################
208 ####################################
202 ### BEAKER SESSION ####
209 ### BEAKER SESSION ####
203 ####################################
210 ####################################
204 ## Type of storage used for the session, current types are
211 ## Type of storage used for the session, current types are
205 ## dbm, file, memcached, database, and memory.
212 ## dbm, file, memcached, database, and memory.
206 ## The storage uses the Container API
213 ## The storage uses the Container API
207 ## that is also used by the cache system.
214 ## that is also used by the cache system.
208
215
209 ## db session ##
216 ## db session ##
210 #beaker.session.type = ext:database
217 #beaker.session.type = ext:database
211 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
218 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
212 #beaker.session.table_name = db_session
219 #beaker.session.table_name = db_session
213
220
214 ## encrypted cookie client side session, good for many instances ##
221 ## encrypted cookie client side session, good for many instances ##
215 #beaker.session.type = cookie
222 #beaker.session.type = cookie
216
223
217 ## file based cookies (default) ##
224 ## file based cookies (default) ##
218 #beaker.session.type = file
225 #beaker.session.type = file
219
226
220
227
221 beaker.session.key = rhodecode
228 beaker.session.key = rhodecode
222 ## secure cookie requires AES python libraries ##
229 ## secure cookie requires AES python libraries ##
223 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
230 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
224 #beaker.session.validate_key = 9712sds2212c--zxc123
231 #beaker.session.validate_key = 9712sds2212c--zxc123
225 ## sets session as invalid if it haven't been accessed for given amount of time
232 ## sets session as invalid if it haven't been accessed for given amount of time
226 beaker.session.timeout = 2592000
233 beaker.session.timeout = 2592000
227 beaker.session.httponly = true
234 beaker.session.httponly = true
228 #beaker.session.cookie_path = /<your-prefix>
235 #beaker.session.cookie_path = /<your-prefix>
229
236
230 ## uncomment for https secure cookie ##
237 ## uncomment for https secure cookie ##
231 beaker.session.secure = false
238 beaker.session.secure = false
232
239
233 ## auto save the session to not to use .save() ##
240 ## auto save the session to not to use .save() ##
234 beaker.session.auto = False
241 beaker.session.auto = False
235
242
236 ## default cookie expiration time in seconds `true` expire at browser close ##
243 ## default cookie expiration time in seconds `true` expire at browser close ##
237 #beaker.session.cookie_expires = 3600
244 #beaker.session.cookie_expires = 3600
238
245
239
246
240 ############################
247 ############################
241 ## ERROR HANDLING SYSTEMS ##
248 ## ERROR HANDLING SYSTEMS ##
242 ############################
249 ############################
243
250
244 ####################
251 ####################
245 ### [errormator] ###
252 ### [errormator] ###
246 ####################
253 ####################
247
254
248 # Errormator is tailored to work with RhodeCode, see
255 # Errormator is tailored to work with RhodeCode, see
249 # http://errormator.com for details how to obtain an account
256 # http://errormator.com for details how to obtain an account
250 # you must install python package `errormator_client` to make it work
257 # you must install python package `errormator_client` to make it work
251
258
252 # errormator enabled
259 # errormator enabled
253 errormator = true
260 errormator = true
254
261
255 errormator.server_url = https://api.errormator.com
262 errormator.server_url = https://api.errormator.com
256 errormator.api_key = YOUR_API_KEY
263 errormator.api_key = YOUR_API_KEY
257
264
258 # TWEAK AMOUNT OF INFO SENT HERE
265 # TWEAK AMOUNT OF INFO SENT HERE
259
266
260 # enables 404 error logging (default False)
267 # enables 404 error logging (default False)
261 errormator.report_404 = false
268 errormator.report_404 = false
262
269
263 # time in seconds after request is considered being slow (default 1)
270 # time in seconds after request is considered being slow (default 1)
264 errormator.slow_request_time = 1
271 errormator.slow_request_time = 1
265
272
266 # record slow requests in application
273 # record slow requests in application
267 # (needs to be enabled for slow datastore recording and time tracking)
274 # (needs to be enabled for slow datastore recording and time tracking)
268 errormator.slow_requests = true
275 errormator.slow_requests = true
269
276
270 # enable hooking to application loggers
277 # enable hooking to application loggers
271 # errormator.logging = true
278 # errormator.logging = true
272
279
273 # minimum log level for log capture
280 # minimum log level for log capture
274 # errormator.logging.level = WARNING
281 # errormator.logging.level = WARNING
275
282
276 # send logs only from erroneous/slow requests
283 # send logs only from erroneous/slow requests
277 # (saves API quota for intensive logging)
284 # (saves API quota for intensive logging)
278 errormator.logging_on_error = false
285 errormator.logging_on_error = false
279
286
280 # list of additonal keywords that should be grabbed from environ object
287 # list of additonal keywords that should be grabbed from environ object
281 # can be string with comma separated list of words in lowercase
288 # can be string with comma separated list of words in lowercase
282 # (by default client will always send following info:
289 # (by default client will always send following info:
283 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
290 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
284 # start with HTTP* this list be extended with additional keywords here
291 # start with HTTP* this list be extended with additional keywords here
285 errormator.environ_keys_whitelist =
292 errormator.environ_keys_whitelist =
286
293
287
294
288 # list of keywords that should be blanked from request object
295 # list of keywords that should be blanked from request object
289 # can be string with comma separated list of words in lowercase
296 # can be string with comma separated list of words in lowercase
290 # (by default client will always blank keys that contain following words
297 # (by default client will always blank keys that contain following words
291 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
298 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
292 # this list be extended with additional keywords set here
299 # this list be extended with additional keywords set here
293 errormator.request_keys_blacklist =
300 errormator.request_keys_blacklist =
294
301
295
302
296 # list of namespaces that should be ignores when gathering log entries
303 # list of namespaces that should be ignores when gathering log entries
297 # can be string with comma separated list of namespaces
304 # can be string with comma separated list of namespaces
298 # (by default the client ignores own entries: errormator_client.client)
305 # (by default the client ignores own entries: errormator_client.client)
299 errormator.log_namespace_blacklist =
306 errormator.log_namespace_blacklist =
300
307
301
308
302 ################
309 ################
303 ### [sentry] ###
310 ### [sentry] ###
304 ################
311 ################
305
312
306 # sentry is a alternative open source error aggregator
313 # sentry is a alternative open source error aggregator
307 # you must install python packages `sentry` and `raven` to enable
314 # you must install python packages `sentry` and `raven` to enable
308
315
309 sentry.dsn = YOUR_DNS
316 sentry.dsn = YOUR_DNS
310 sentry.servers =
317 sentry.servers =
311 sentry.name =
318 sentry.name =
312 sentry.key =
319 sentry.key =
313 sentry.public_key =
320 sentry.public_key =
314 sentry.secret_key =
321 sentry.secret_key =
315 sentry.project =
322 sentry.project =
316 sentry.site =
323 sentry.site =
317 sentry.include_paths =
324 sentry.include_paths =
318 sentry.exclude_paths =
325 sentry.exclude_paths =
319
326
320
327
321 ################################################################################
328 ################################################################################
322 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
329 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
323 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
330 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
324 ## execute malicious code after an exception is raised. ##
331 ## execute malicious code after an exception is raised. ##
325 ################################################################################
332 ################################################################################
326 #set debug = false
333 #set debug = false
327
334
328 ##################################
335 ##################################
329 ### LOGVIEW CONFIG ###
336 ### LOGVIEW CONFIG ###
330 ##################################
337 ##################################
331 logview.sqlalchemy = #faa
338 logview.sqlalchemy = #faa
332 logview.pylons.templating = #bfb
339 logview.pylons.templating = #bfb
333 logview.pylons.util = #eee
340 logview.pylons.util = #eee
334
341
335 #########################################################
342 #########################################################
336 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
343 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
337 #########################################################
344 #########################################################
338 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
345 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
339 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
346 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
340 sqlalchemy.db1.echo = false
347 sqlalchemy.db1.echo = false
341 sqlalchemy.db1.pool_recycle = 3600
348 sqlalchemy.db1.pool_recycle = 3600
342 sqlalchemy.db1.convert_unicode = true
349 sqlalchemy.db1.convert_unicode = true
343
350
344 ################################
351 ################################
345 ### LOGGING CONFIGURATION ####
352 ### LOGGING CONFIGURATION ####
346 ################################
353 ################################
347 [loggers]
354 [loggers]
348 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
355 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
349
356
350 [handlers]
357 [handlers]
351 keys = console, console_sql
358 keys = console, console_sql
352
359
353 [formatters]
360 [formatters]
354 keys = generic, color_formatter, color_formatter_sql
361 keys = generic, color_formatter, color_formatter_sql
355
362
356 #############
363 #############
357 ## LOGGERS ##
364 ## LOGGERS ##
358 #############
365 #############
359 [logger_root]
366 [logger_root]
360 level = NOTSET
367 level = NOTSET
361 handlers = console
368 handlers = console
362
369
363 [logger_routes]
370 [logger_routes]
364 level = DEBUG
371 level = DEBUG
365 handlers =
372 handlers =
366 qualname = routes.middleware
373 qualname = routes.middleware
367 # "level = DEBUG" logs the route matched and routing variables.
374 # "level = DEBUG" logs the route matched and routing variables.
368 propagate = 1
375 propagate = 1
369
376
370 [logger_beaker]
377 [logger_beaker]
371 level = DEBUG
378 level = DEBUG
372 handlers =
379 handlers =
373 qualname = beaker.container
380 qualname = beaker.container
374 propagate = 1
381 propagate = 1
375
382
376 [logger_templates]
383 [logger_templates]
377 level = INFO
384 level = INFO
378 handlers =
385 handlers =
379 qualname = pylons.templating
386 qualname = pylons.templating
380 propagate = 1
387 propagate = 1
381
388
382 [logger_rhodecode]
389 [logger_rhodecode]
383 level = DEBUG
390 level = DEBUG
384 handlers =
391 handlers =
385 qualname = rhodecode
392 qualname = rhodecode
386 propagate = 1
393 propagate = 1
387
394
388 [logger_sqlalchemy]
395 [logger_sqlalchemy]
389 level = INFO
396 level = INFO
390 handlers = console_sql
397 handlers = console_sql
391 qualname = sqlalchemy.engine
398 qualname = sqlalchemy.engine
392 propagate = 0
399 propagate = 0
393
400
394 [logger_whoosh_indexer]
401 [logger_whoosh_indexer]
395 level = DEBUG
402 level = DEBUG
396 handlers =
403 handlers =
397 qualname = whoosh_indexer
404 qualname = whoosh_indexer
398 propagate = 1
405 propagate = 1
399
406
400 ##############
407 ##############
401 ## HANDLERS ##
408 ## HANDLERS ##
402 ##############
409 ##############
403
410
404 [handler_console]
411 [handler_console]
405 class = StreamHandler
412 class = StreamHandler
406 args = (sys.stderr,)
413 args = (sys.stderr,)
407 level = DEBUG
414 level = DEBUG
408 formatter = color_formatter
415 formatter = color_formatter
409
416
410 [handler_console_sql]
417 [handler_console_sql]
411 class = StreamHandler
418 class = StreamHandler
412 args = (sys.stderr,)
419 args = (sys.stderr,)
413 level = DEBUG
420 level = DEBUG
414 formatter = color_formatter_sql
421 formatter = color_formatter_sql
415
422
416 ################
423 ################
417 ## FORMATTERS ##
424 ## FORMATTERS ##
418 ################
425 ################
419
426
420 [formatter_generic]
427 [formatter_generic]
421 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
428 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
422 datefmt = %Y-%m-%d %H:%M:%S
429 datefmt = %Y-%m-%d %H:%M:%S
423
430
424 [formatter_color_formatter]
431 [formatter_color_formatter]
425 class=rhodecode.lib.colored_formatter.ColorFormatter
432 class=rhodecode.lib.colored_formatter.ColorFormatter
426 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
433 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
427 datefmt = %Y-%m-%d %H:%M:%S
434 datefmt = %Y-%m-%d %H:%M:%S
428
435
429 [formatter_color_formatter_sql]
436 [formatter_color_formatter_sql]
430 class=rhodecode.lib.colored_formatter.ColorFormatterSql
437 class=rhodecode.lib.colored_formatter.ColorFormatterSql
431 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
438 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
432 datefmt = %Y-%m-%d %H:%M:%S
439 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,432 +1,439 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 ##nr of threads to spawn
33 ##nr of threads to spawn
33 #threadpool_workers = 5
34 #threadpool_workers = 5
34
35
35 ##max request before thread respawn
36 ##max request before thread respawn
36 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
37
38
38 ##option to use threads of process
39 ##option to use threads of process
39 #use_threadpool = true
40 #use_threadpool = true
40
41
41 #use = egg:Paste#http
42 #use = egg:Paste#http
43
44 #WAITRESS
45 threads = 5
42 use = egg:waitress#main
46 use = egg:waitress#main
47
43 host = 127.0.0.1
48 host = 127.0.0.1
44 port = 8001
49 port = 8001
45
50
46 [filter:proxy-prefix]
51 [filter:proxy-prefix]
47 # prefix middleware for rc
52 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
53 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
54 prefix = /<your-prefix>
50
55
51 [app:main]
56 [app:main]
52 use = egg:rhodecode
57 use = egg:rhodecode
53 #filter-with = proxy-prefix
58 #filter-with = proxy-prefix
54 full_stack = true
59 full_stack = true
55 static_files = true
60 static_files = true
56 # Optional Languages
61 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW
62 # en, fr, ja, pt_BR, zh_CN, zh_TW, pl
58 lang = en
63 lang = en
59 cache_dir = %(here)s/data
64 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
65 index_dir = %(here)s/data/index
61 app_instance_uuid = rc-production
66 app_instance_uuid = rc-production
62 cut_off_limit = 256000
67 cut_off_limit = 256000
63 vcs_full_cache = True
68 vcs_full_cache = True
64 force_https = false
69 force_https = false
65 commit_parse_limit = 50
70 commit_parse_limit = 50
71 # number of items displayed in lightweight dashboard before paginating
72 dashboard_items = 100
66 use_gravatar = true
73 use_gravatar = true
67
74
68 ## RSS feed options
75 ## RSS feed options
69
76
70 rss_cut_off_limit = 256000
77 rss_cut_off_limit = 256000
71 rss_items_per_page = 10
78 rss_items_per_page = 10
72 rss_include_diff = false
79 rss_include_diff = false
73
80
74
81
75 ## alternative_gravatar_url allows you to use your own avatar server application
82 ## alternative_gravatar_url allows you to use your own avatar server application
76 ## the following parts of the URL will be replaced
83 ## the following parts of the URL will be replaced
77 ## {email} user email
84 ## {email} user email
78 ## {md5email} md5 hash of the user email (like at gravatar.com)
85 ## {md5email} md5 hash of the user email (like at gravatar.com)
79 ## {size} size of the image that is expected from the server application
86 ## {size} size of the image that is expected from the server application
80 ## {scheme} http/https from RhodeCode server
87 ## {scheme} http/https from RhodeCode server
81 ## {netloc} network location from RhodeCode server
88 ## {netloc} network location from RhodeCode server
82 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
89 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
83 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
90 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
84
91
85 container_auth_enabled = false
92 container_auth_enabled = false
86 proxypass_auth_enabled = false
93 proxypass_auth_enabled = false
87 ## default encoding used to convert from and to unicode
94 ## default encoding used to convert from and to unicode
88 ## can be also a comma seperated list of encoding in case of mixed encodings
95 ## can be also a comma seperated list of encoding in case of mixed encodings
89 default_encoding = utf8
96 default_encoding = utf8
90
97
91 ## overwrite schema of clone url
98 ## overwrite schema of clone url
92 ## available vars:
99 ## available vars:
93 ## scheme - http/https
100 ## scheme - http/https
94 ## user - current user
101 ## user - current user
95 ## pass - password
102 ## pass - password
96 ## netloc - network location
103 ## netloc - network location
97 ## path - usually repo_name
104 ## path - usually repo_name
98
105
99 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
106 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
100
107
101 ## issue tracking mapping for commits messages
108 ## issue tracking mapping for commits messages
102 ## comment out issue_pat, issue_server, issue_prefix to enable
109 ## comment out issue_pat, issue_server, issue_prefix to enable
103
110
104 ## pattern to get the issues from commit messages
111 ## pattern to get the issues from commit messages
105 ## default one used here is #<numbers> with a regex passive group for `#`
112 ## default one used here is #<numbers> with a regex passive group for `#`
106 ## {id} will be all groups matched from this pattern
113 ## {id} will be all groups matched from this pattern
107
114
108 issue_pat = (?:\s*#)(\d+)
115 issue_pat = (?:\s*#)(\d+)
109
116
110 ## server url to the issue, each {id} will be replaced with match
117 ## server url to the issue, each {id} will be replaced with match
111 ## fetched from the regex and {repo} is replaced with full repository name
118 ## fetched from the regex and {repo} is replaced with full repository name
112 ## including groups {repo_name} is replaced with just name of repo
119 ## including groups {repo_name} is replaced with just name of repo
113
120
114 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
121 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
115
122
116 ## prefix to add to link to indicate it's an url
123 ## prefix to add to link to indicate it's an url
117 ## #314 will be replaced by <issue_prefix><id>
124 ## #314 will be replaced by <issue_prefix><id>
118
125
119 issue_prefix = #
126 issue_prefix = #
120
127
121 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
128 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
122 ## multiple patterns, to other issues server, wiki or others
129 ## multiple patterns, to other issues server, wiki or others
123 ## below an example how to create a wiki pattern
130 ## below an example how to create a wiki pattern
124 # #wiki-some-id -> https://mywiki.com/some-id
131 # #wiki-some-id -> https://mywiki.com/some-id
125
132
126 #issue_pat_wiki = (?:wiki-)(.+)
133 #issue_pat_wiki = (?:wiki-)(.+)
127 #issue_server_link_wiki = https://mywiki.com/{id}
134 #issue_server_link_wiki = https://mywiki.com/{id}
128 #issue_prefix_wiki = WIKI-
135 #issue_prefix_wiki = WIKI-
129
136
130
137
131 ## instance-id prefix
138 ## instance-id prefix
132 ## a prefix key for this instance used for cache invalidation when running
139 ## a prefix key for this instance used for cache invalidation when running
133 ## multiple instances of rhodecode, make sure it's globally unique for
140 ## multiple instances of rhodecode, make sure it's globally unique for
134 ## all running rhodecode instances. Leave empty if you don't use it
141 ## all running rhodecode instances. Leave empty if you don't use it
135 instance_id =
142 instance_id =
136
143
137 ## alternative return HTTP header for failed authentication. Default HTTP
144 ## alternative return HTTP header for failed authentication. Default HTTP
138 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
145 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
139 ## handling that. Set this variable to 403 to return HTTPForbidden
146 ## handling that. Set this variable to 403 to return HTTPForbidden
140 auth_ret_code =
147 auth_ret_code =
141
148
142 ####################################
149 ####################################
143 ### CELERY CONFIG ####
150 ### CELERY CONFIG ####
144 ####################################
151 ####################################
145 use_celery = false
152 use_celery = false
146 broker.host = localhost
153 broker.host = localhost
147 broker.vhost = rabbitmqhost
154 broker.vhost = rabbitmqhost
148 broker.port = 5672
155 broker.port = 5672
149 broker.user = rabbitmq
156 broker.user = rabbitmq
150 broker.password = qweqwe
157 broker.password = qweqwe
151
158
152 celery.imports = rhodecode.lib.celerylib.tasks
159 celery.imports = rhodecode.lib.celerylib.tasks
153
160
154 celery.result.backend = amqp
161 celery.result.backend = amqp
155 celery.result.dburi = amqp://
162 celery.result.dburi = amqp://
156 celery.result.serialier = json
163 celery.result.serialier = json
157
164
158 #celery.send.task.error.emails = true
165 #celery.send.task.error.emails = true
159 #celery.amqp.task.result.expires = 18000
166 #celery.amqp.task.result.expires = 18000
160
167
161 celeryd.concurrency = 2
168 celeryd.concurrency = 2
162 #celeryd.log.file = celeryd.log
169 #celeryd.log.file = celeryd.log
163 celeryd.log.level = debug
170 celeryd.log.level = debug
164 celeryd.max.tasks.per.child = 1
171 celeryd.max.tasks.per.child = 1
165
172
166 #tasks will never be sent to the queue, but executed locally instead.
173 #tasks will never be sent to the queue, but executed locally instead.
167 celery.always.eager = false
174 celery.always.eager = false
168
175
169 ####################################
176 ####################################
170 ### BEAKER CACHE ####
177 ### BEAKER CACHE ####
171 ####################################
178 ####################################
172 beaker.cache.data_dir=%(here)s/data/cache/data
179 beaker.cache.data_dir=%(here)s/data/cache/data
173 beaker.cache.lock_dir=%(here)s/data/cache/lock
180 beaker.cache.lock_dir=%(here)s/data/cache/lock
174
181
175 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
182 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
176
183
177 beaker.cache.super_short_term.type=memory
184 beaker.cache.super_short_term.type=memory
178 beaker.cache.super_short_term.expire=10
185 beaker.cache.super_short_term.expire=10
179 beaker.cache.super_short_term.key_length = 256
186 beaker.cache.super_short_term.key_length = 256
180
187
181 beaker.cache.short_term.type=memory
188 beaker.cache.short_term.type=memory
182 beaker.cache.short_term.expire=60
189 beaker.cache.short_term.expire=60
183 beaker.cache.short_term.key_length = 256
190 beaker.cache.short_term.key_length = 256
184
191
185 beaker.cache.long_term.type=memory
192 beaker.cache.long_term.type=memory
186 beaker.cache.long_term.expire=36000
193 beaker.cache.long_term.expire=36000
187 beaker.cache.long_term.key_length = 256
194 beaker.cache.long_term.key_length = 256
188
195
189 beaker.cache.sql_cache_short.type=memory
196 beaker.cache.sql_cache_short.type=memory
190 beaker.cache.sql_cache_short.expire=10
197 beaker.cache.sql_cache_short.expire=10
191 beaker.cache.sql_cache_short.key_length = 256
198 beaker.cache.sql_cache_short.key_length = 256
192
199
193 beaker.cache.sql_cache_med.type=memory
200 beaker.cache.sql_cache_med.type=memory
194 beaker.cache.sql_cache_med.expire=360
201 beaker.cache.sql_cache_med.expire=360
195 beaker.cache.sql_cache_med.key_length = 256
202 beaker.cache.sql_cache_med.key_length = 256
196
203
197 beaker.cache.sql_cache_long.type=file
204 beaker.cache.sql_cache_long.type=file
198 beaker.cache.sql_cache_long.expire=3600
205 beaker.cache.sql_cache_long.expire=3600
199 beaker.cache.sql_cache_long.key_length = 256
206 beaker.cache.sql_cache_long.key_length = 256
200
207
201 ####################################
208 ####################################
202 ### BEAKER SESSION ####
209 ### BEAKER SESSION ####
203 ####################################
210 ####################################
204 ## Type of storage used for the session, current types are
211 ## Type of storage used for the session, current types are
205 ## dbm, file, memcached, database, and memory.
212 ## dbm, file, memcached, database, and memory.
206 ## The storage uses the Container API
213 ## The storage uses the Container API
207 ## that is also used by the cache system.
214 ## that is also used by the cache system.
208
215
209 ## db session ##
216 ## db session ##
210 #beaker.session.type = ext:database
217 #beaker.session.type = ext:database
211 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
218 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
212 #beaker.session.table_name = db_session
219 #beaker.session.table_name = db_session
213
220
214 ## encrypted cookie client side session, good for many instances ##
221 ## encrypted cookie client side session, good for many instances ##
215 #beaker.session.type = cookie
222 #beaker.session.type = cookie
216
223
217 ## file based cookies (default) ##
224 ## file based cookies (default) ##
218 #beaker.session.type = file
225 #beaker.session.type = file
219
226
220
227
221 beaker.session.key = rhodecode
228 beaker.session.key = rhodecode
222 ## secure cookie requires AES python libraries ##
229 ## secure cookie requires AES python libraries ##
223 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
230 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
224 #beaker.session.validate_key = 9712sds2212c--zxc123
231 #beaker.session.validate_key = 9712sds2212c--zxc123
225 ## sets session as invalid if it haven't been accessed for given amount of time
232 ## sets session as invalid if it haven't been accessed for given amount of time
226 beaker.session.timeout = 2592000
233 beaker.session.timeout = 2592000
227 beaker.session.httponly = true
234 beaker.session.httponly = true
228 #beaker.session.cookie_path = /<your-prefix>
235 #beaker.session.cookie_path = /<your-prefix>
229
236
230 ## uncomment for https secure cookie ##
237 ## uncomment for https secure cookie ##
231 beaker.session.secure = false
238 beaker.session.secure = false
232
239
233 ## auto save the session to not to use .save() ##
240 ## auto save the session to not to use .save() ##
234 beaker.session.auto = False
241 beaker.session.auto = False
235
242
236 ## default cookie expiration time in seconds `true` expire at browser close ##
243 ## default cookie expiration time in seconds `true` expire at browser close ##
237 #beaker.session.cookie_expires = 3600
244 #beaker.session.cookie_expires = 3600
238
245
239
246
240 ############################
247 ############################
241 ## ERROR HANDLING SYSTEMS ##
248 ## ERROR HANDLING SYSTEMS ##
242 ############################
249 ############################
243
250
244 ####################
251 ####################
245 ### [errormator] ###
252 ### [errormator] ###
246 ####################
253 ####################
247
254
248 # Errormator is tailored to work with RhodeCode, see
255 # Errormator is tailored to work with RhodeCode, see
249 # http://errormator.com for details how to obtain an account
256 # http://errormator.com for details how to obtain an account
250 # you must install python package `errormator_client` to make it work
257 # you must install python package `errormator_client` to make it work
251
258
252 # errormator enabled
259 # errormator enabled
253 errormator = true
260 errormator = true
254
261
255 errormator.server_url = https://api.errormator.com
262 errormator.server_url = https://api.errormator.com
256 errormator.api_key = YOUR_API_KEY
263 errormator.api_key = YOUR_API_KEY
257
264
258 # TWEAK AMOUNT OF INFO SENT HERE
265 # TWEAK AMOUNT OF INFO SENT HERE
259
266
260 # enables 404 error logging (default False)
267 # enables 404 error logging (default False)
261 errormator.report_404 = false
268 errormator.report_404 = false
262
269
263 # time in seconds after request is considered being slow (default 1)
270 # time in seconds after request is considered being slow (default 1)
264 errormator.slow_request_time = 1
271 errormator.slow_request_time = 1
265
272
266 # record slow requests in application
273 # record slow requests in application
267 # (needs to be enabled for slow datastore recording and time tracking)
274 # (needs to be enabled for slow datastore recording and time tracking)
268 errormator.slow_requests = true
275 errormator.slow_requests = true
269
276
270 # enable hooking to application loggers
277 # enable hooking to application loggers
271 # errormator.logging = true
278 # errormator.logging = true
272
279
273 # minimum log level for log capture
280 # minimum log level for log capture
274 # errormator.logging.level = WARNING
281 # errormator.logging.level = WARNING
275
282
276 # send logs only from erroneous/slow requests
283 # send logs only from erroneous/slow requests
277 # (saves API quota for intensive logging)
284 # (saves API quota for intensive logging)
278 errormator.logging_on_error = false
285 errormator.logging_on_error = false
279
286
280 # list of additonal keywords that should be grabbed from environ object
287 # list of additonal keywords that should be grabbed from environ object
281 # can be string with comma separated list of words in lowercase
288 # can be string with comma separated list of words in lowercase
282 # (by default client will always send following info:
289 # (by default client will always send following info:
283 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
290 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
284 # start with HTTP* this list be extended with additional keywords here
291 # start with HTTP* this list be extended with additional keywords here
285 errormator.environ_keys_whitelist =
292 errormator.environ_keys_whitelist =
286
293
287
294
288 # list of keywords that should be blanked from request object
295 # list of keywords that should be blanked from request object
289 # can be string with comma separated list of words in lowercase
296 # can be string with comma separated list of words in lowercase
290 # (by default client will always blank keys that contain following words
297 # (by default client will always blank keys that contain following words
291 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
298 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
292 # this list be extended with additional keywords set here
299 # this list be extended with additional keywords set here
293 errormator.request_keys_blacklist =
300 errormator.request_keys_blacklist =
294
301
295
302
296 # list of namespaces that should be ignores when gathering log entries
303 # list of namespaces that should be ignores when gathering log entries
297 # can be string with comma separated list of namespaces
304 # can be string with comma separated list of namespaces
298 # (by default the client ignores own entries: errormator_client.client)
305 # (by default the client ignores own entries: errormator_client.client)
299 errormator.log_namespace_blacklist =
306 errormator.log_namespace_blacklist =
300
307
301
308
302 ################
309 ################
303 ### [sentry] ###
310 ### [sentry] ###
304 ################
311 ################
305
312
306 # sentry is a alternative open source error aggregator
313 # sentry is a alternative open source error aggregator
307 # you must install python packages `sentry` and `raven` to enable
314 # you must install python packages `sentry` and `raven` to enable
308
315
309 sentry.dsn = YOUR_DNS
316 sentry.dsn = YOUR_DNS
310 sentry.servers =
317 sentry.servers =
311 sentry.name =
318 sentry.name =
312 sentry.key =
319 sentry.key =
313 sentry.public_key =
320 sentry.public_key =
314 sentry.secret_key =
321 sentry.secret_key =
315 sentry.project =
322 sentry.project =
316 sentry.site =
323 sentry.site =
317 sentry.include_paths =
324 sentry.include_paths =
318 sentry.exclude_paths =
325 sentry.exclude_paths =
319
326
320
327
321 ################################################################################
328 ################################################################################
322 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
329 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
323 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
330 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
324 ## execute malicious code after an exception is raised. ##
331 ## execute malicious code after an exception is raised. ##
325 ################################################################################
332 ################################################################################
326 set debug = false
333 set debug = false
327
334
328 ##################################
335 ##################################
329 ### LOGVIEW CONFIG ###
336 ### LOGVIEW CONFIG ###
330 ##################################
337 ##################################
331 logview.sqlalchemy = #faa
338 logview.sqlalchemy = #faa
332 logview.pylons.templating = #bfb
339 logview.pylons.templating = #bfb
333 logview.pylons.util = #eee
340 logview.pylons.util = #eee
334
341
335 #########################################################
342 #########################################################
336 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
343 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
337 #########################################################
344 #########################################################
338 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
345 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
339 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
346 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
340 sqlalchemy.db1.echo = false
347 sqlalchemy.db1.echo = false
341 sqlalchemy.db1.pool_recycle = 3600
348 sqlalchemy.db1.pool_recycle = 3600
342 sqlalchemy.db1.convert_unicode = true
349 sqlalchemy.db1.convert_unicode = true
343
350
344 ################################
351 ################################
345 ### LOGGING CONFIGURATION ####
352 ### LOGGING CONFIGURATION ####
346 ################################
353 ################################
347 [loggers]
354 [loggers]
348 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
355 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
349
356
350 [handlers]
357 [handlers]
351 keys = console, console_sql
358 keys = console, console_sql
352
359
353 [formatters]
360 [formatters]
354 keys = generic, color_formatter, color_formatter_sql
361 keys = generic, color_formatter, color_formatter_sql
355
362
356 #############
363 #############
357 ## LOGGERS ##
364 ## LOGGERS ##
358 #############
365 #############
359 [logger_root]
366 [logger_root]
360 level = NOTSET
367 level = NOTSET
361 handlers = console
368 handlers = console
362
369
363 [logger_routes]
370 [logger_routes]
364 level = DEBUG
371 level = DEBUG
365 handlers =
372 handlers =
366 qualname = routes.middleware
373 qualname = routes.middleware
367 # "level = DEBUG" logs the route matched and routing variables.
374 # "level = DEBUG" logs the route matched and routing variables.
368 propagate = 1
375 propagate = 1
369
376
370 [logger_beaker]
377 [logger_beaker]
371 level = DEBUG
378 level = DEBUG
372 handlers =
379 handlers =
373 qualname = beaker.container
380 qualname = beaker.container
374 propagate = 1
381 propagate = 1
375
382
376 [logger_templates]
383 [logger_templates]
377 level = INFO
384 level = INFO
378 handlers =
385 handlers =
379 qualname = pylons.templating
386 qualname = pylons.templating
380 propagate = 1
387 propagate = 1
381
388
382 [logger_rhodecode]
389 [logger_rhodecode]
383 level = DEBUG
390 level = DEBUG
384 handlers =
391 handlers =
385 qualname = rhodecode
392 qualname = rhodecode
386 propagate = 1
393 propagate = 1
387
394
388 [logger_sqlalchemy]
395 [logger_sqlalchemy]
389 level = INFO
396 level = INFO
390 handlers = console_sql
397 handlers = console_sql
391 qualname = sqlalchemy.engine
398 qualname = sqlalchemy.engine
392 propagate = 0
399 propagate = 0
393
400
394 [logger_whoosh_indexer]
401 [logger_whoosh_indexer]
395 level = DEBUG
402 level = DEBUG
396 handlers =
403 handlers =
397 qualname = whoosh_indexer
404 qualname = whoosh_indexer
398 propagate = 1
405 propagate = 1
399
406
400 ##############
407 ##############
401 ## HANDLERS ##
408 ## HANDLERS ##
402 ##############
409 ##############
403
410
404 [handler_console]
411 [handler_console]
405 class = StreamHandler
412 class = StreamHandler
406 args = (sys.stderr,)
413 args = (sys.stderr,)
407 level = INFO
414 level = INFO
408 formatter = generic
415 formatter = generic
409
416
410 [handler_console_sql]
417 [handler_console_sql]
411 class = StreamHandler
418 class = StreamHandler
412 args = (sys.stderr,)
419 args = (sys.stderr,)
413 level = WARN
420 level = WARN
414 formatter = generic
421 formatter = generic
415
422
416 ################
423 ################
417 ## FORMATTERS ##
424 ## FORMATTERS ##
418 ################
425 ################
419
426
420 [formatter_generic]
427 [formatter_generic]
421 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
428 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
422 datefmt = %Y-%m-%d %H:%M:%S
429 datefmt = %Y-%m-%d %H:%M:%S
423
430
424 [formatter_color_formatter]
431 [formatter_color_formatter]
425 class=rhodecode.lib.colored_formatter.ColorFormatter
432 class=rhodecode.lib.colored_formatter.ColorFormatter
426 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
433 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
427 datefmt = %Y-%m-%d %H:%M:%S
434 datefmt = %Y-%m-%d %H:%M:%S
428
435
429 [formatter_color_formatter_sql]
436 [formatter_color_formatter_sql]
430 class=rhodecode.lib.colored_formatter.ColorFormatterSql
437 class=rhodecode.lib.colored_formatter.ColorFormatterSql
431 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
438 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
432 datefmt = %Y-%m-%d %H:%M:%S
439 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,442 +1,449 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 ##nr of threads to spawn
33 ##nr of threads to spawn
33 #threadpool_workers = 5
34 #threadpool_workers = 5
34
35
35 ##max request before thread respawn
36 ##max request before thread respawn
36 #threadpool_max_requests = 10
37 #threadpool_max_requests = 10
37
38
38 ##option to use threads of process
39 ##option to use threads of process
39 #use_threadpool = true
40 #use_threadpool = true
40
41
41 #use = egg:Paste#http
42 #use = egg:Paste#http
43
44 #WAITRESS
45 threads = 5
42 use = egg:waitress#main
46 use = egg:waitress#main
47
43 host = 127.0.0.1
48 host = 127.0.0.1
44 port = 5000
49 port = 5000
45
50
46 [filter:proxy-prefix]
51 [filter:proxy-prefix]
47 # prefix middleware for rc
52 # prefix middleware for rc
48 use = egg:PasteDeploy#prefix
53 use = egg:PasteDeploy#prefix
49 prefix = /<your-prefix>
54 prefix = /<your-prefix>
50
55
51 [app:main]
56 [app:main]
52 use = egg:rhodecode
57 use = egg:rhodecode
53 #filter-with = proxy-prefix
58 #filter-with = proxy-prefix
54 full_stack = true
59 full_stack = true
55 static_files = true
60 static_files = true
56 # Optional Languages
61 # Optional Languages
57 # en, fr, ja, pt_BR, zh_CN, zh_TW, pl
62 # en, fr, ja, pt_BR, zh_CN, zh_TW, pl
58 lang = en
63 lang = en
59 cache_dir = %(here)s/data
64 cache_dir = %(here)s/data
60 index_dir = %(here)s/data/index
65 index_dir = %(here)s/data/index
61 app_instance_uuid = ${app_instance_uuid}
66 app_instance_uuid = ${app_instance_uuid}
62 cut_off_limit = 256000
67 cut_off_limit = 256000
63 vcs_full_cache = True
68 vcs_full_cache = True
64 force_https = false
69 force_https = false
65 commit_parse_limit = 50
70 commit_parse_limit = 50
71 # number of items displayed in lightweight dashboard before paginating
72 dashboard_items = 100
66 use_gravatar = true
73 use_gravatar = true
67
74
68 ## RSS feed options
75 ## RSS feed options
69
76
70 rss_cut_off_limit = 256000
77 rss_cut_off_limit = 256000
71 rss_items_per_page = 10
78 rss_items_per_page = 10
72 rss_include_diff = false
79 rss_include_diff = false
73
80
74
81
75 ## alternative_gravatar_url allows you to use your own avatar server application
82 ## alternative_gravatar_url allows you to use your own avatar server application
76 ## the following parts of the URL will be replaced
83 ## the following parts of the URL will be replaced
77 ## {email} user email
84 ## {email} user email
78 ## {md5email} md5 hash of the user email (like at gravatar.com)
85 ## {md5email} md5 hash of the user email (like at gravatar.com)
79 ## {size} size of the image that is expected from the server application
86 ## {size} size of the image that is expected from the server application
80 ## {scheme} http/https from RhodeCode server
87 ## {scheme} http/https from RhodeCode server
81 ## {netloc} network location from RhodeCode server
88 ## {netloc} network location from RhodeCode server
82 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
89 #alternative_gravatar_url = http://myavatarserver.com/getbyemail/{email}/{size}
83 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
90 #alternative_gravatar_url = http://myavatarserver.com/getbymd5/{md5email}?s={size}
84
91
85 container_auth_enabled = false
92 container_auth_enabled = false
86 proxypass_auth_enabled = false
93 proxypass_auth_enabled = false
87 ## default encoding used to convert from and to unicode
94 ## default encoding used to convert from and to unicode
88 ## can be also a comma seperated list of encoding in case of mixed encodings
95 ## can be also a comma seperated list of encoding in case of mixed encodings
89 default_encoding = utf8
96 default_encoding = utf8
90
97
91 ## overwrite schema of clone url
98 ## overwrite schema of clone url
92 ## available vars:
99 ## available vars:
93 ## scheme - http/https
100 ## scheme - http/https
94 ## user - current user
101 ## user - current user
95 ## pass - password
102 ## pass - password
96 ## netloc - network location
103 ## netloc - network location
97 ## path - usually repo_name
104 ## path - usually repo_name
98
105
99 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
106 #clone_uri = {scheme}://{user}{pass}{netloc}{path}
100
107
101 ## issue tracking mapping for commits messages
108 ## issue tracking mapping for commits messages
102 ## comment out issue_pat, issue_server, issue_prefix to enable
109 ## comment out issue_pat, issue_server, issue_prefix to enable
103
110
104 ## pattern to get the issues from commit messages
111 ## pattern to get the issues from commit messages
105 ## default one used here is #<numbers> with a regex passive group for `#`
112 ## default one used here is #<numbers> with a regex passive group for `#`
106 ## {id} will be all groups matched from this pattern
113 ## {id} will be all groups matched from this pattern
107
114
108 issue_pat = (?:\s*#)(\d+)
115 issue_pat = (?:\s*#)(\d+)
109
116
110 ## server url to the issue, each {id} will be replaced with match
117 ## server url to the issue, each {id} will be replaced with match
111 ## fetched from the regex and {repo} is replaced with full repository name
118 ## fetched from the regex and {repo} is replaced with full repository name
112 ## including groups {repo_name} is replaced with just name of repo
119 ## including groups {repo_name} is replaced with just name of repo
113
120
114 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
121 issue_server_link = https://myissueserver.com/{repo}/issue/{id}
115
122
116 ## prefix to add to link to indicate it's an url
123 ## prefix to add to link to indicate it's an url
117 ## #314 will be replaced by <issue_prefix><id>
124 ## #314 will be replaced by <issue_prefix><id>
118
125
119 issue_prefix = #
126 issue_prefix = #
120
127
121 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
128 ## issue_pat, issue_server_link, issue_prefix can have suffixes to specify
122 ## multiple patterns, to other issues server, wiki or others
129 ## multiple patterns, to other issues server, wiki or others
123 ## below an example how to create a wiki pattern
130 ## below an example how to create a wiki pattern
124 # #wiki-some-id -> https://mywiki.com/some-id
131 # #wiki-some-id -> https://mywiki.com/some-id
125
132
126 #issue_pat_wiki = (?:wiki-)(.+)
133 #issue_pat_wiki = (?:wiki-)(.+)
127 #issue_server_link_wiki = https://mywiki.com/{id}
134 #issue_server_link_wiki = https://mywiki.com/{id}
128 #issue_prefix_wiki = WIKI-
135 #issue_prefix_wiki = WIKI-
129
136
130
137
131 ## instance-id prefix
138 ## instance-id prefix
132 ## a prefix key for this instance used for cache invalidation when running
139 ## a prefix key for this instance used for cache invalidation when running
133 ## multiple instances of rhodecode, make sure it's globally unique for
140 ## multiple instances of rhodecode, make sure it's globally unique for
134 ## all running rhodecode instances. Leave empty if you don't use it
141 ## all running rhodecode instances. Leave empty if you don't use it
135 instance_id =
142 instance_id =
136
143
137 ## alternative return HTTP header for failed authentication. Default HTTP
144 ## alternative return HTTP header for failed authentication. Default HTTP
138 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
145 ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with
139 ## handling that. Set this variable to 403 to return HTTPForbidden
146 ## handling that. Set this variable to 403 to return HTTPForbidden
140 auth_ret_code =
147 auth_ret_code =
141
148
142 ####################################
149 ####################################
143 ### CELERY CONFIG ####
150 ### CELERY CONFIG ####
144 ####################################
151 ####################################
145 use_celery = false
152 use_celery = false
146 broker.host = localhost
153 broker.host = localhost
147 broker.vhost = rabbitmqhost
154 broker.vhost = rabbitmqhost
148 broker.port = 5672
155 broker.port = 5672
149 broker.user = rabbitmq
156 broker.user = rabbitmq
150 broker.password = qweqwe
157 broker.password = qweqwe
151
158
152 celery.imports = rhodecode.lib.celerylib.tasks
159 celery.imports = rhodecode.lib.celerylib.tasks
153
160
154 celery.result.backend = amqp
161 celery.result.backend = amqp
155 celery.result.dburi = amqp://
162 celery.result.dburi = amqp://
156 celery.result.serialier = json
163 celery.result.serialier = json
157
164
158 #celery.send.task.error.emails = true
165 #celery.send.task.error.emails = true
159 #celery.amqp.task.result.expires = 18000
166 #celery.amqp.task.result.expires = 18000
160
167
161 celeryd.concurrency = 2
168 celeryd.concurrency = 2
162 #celeryd.log.file = celeryd.log
169 #celeryd.log.file = celeryd.log
163 celeryd.log.level = debug
170 celeryd.log.level = debug
164 celeryd.max.tasks.per.child = 1
171 celeryd.max.tasks.per.child = 1
165
172
166 #tasks will never be sent to the queue, but executed locally instead.
173 #tasks will never be sent to the queue, but executed locally instead.
167 celery.always.eager = false
174 celery.always.eager = false
168
175
169 ####################################
176 ####################################
170 ### BEAKER CACHE ####
177 ### BEAKER CACHE ####
171 ####################################
178 ####################################
172 beaker.cache.data_dir=%(here)s/data/cache/data
179 beaker.cache.data_dir=%(here)s/data/cache/data
173 beaker.cache.lock_dir=%(here)s/data/cache/lock
180 beaker.cache.lock_dir=%(here)s/data/cache/lock
174
181
175 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
182 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
176
183
177 beaker.cache.super_short_term.type=memory
184 beaker.cache.super_short_term.type=memory
178 beaker.cache.super_short_term.expire=10
185 beaker.cache.super_short_term.expire=10
179 beaker.cache.super_short_term.key_length = 256
186 beaker.cache.super_short_term.key_length = 256
180
187
181 beaker.cache.short_term.type=memory
188 beaker.cache.short_term.type=memory
182 beaker.cache.short_term.expire=60
189 beaker.cache.short_term.expire=60
183 beaker.cache.short_term.key_length = 256
190 beaker.cache.short_term.key_length = 256
184
191
185 beaker.cache.long_term.type=memory
192 beaker.cache.long_term.type=memory
186 beaker.cache.long_term.expire=36000
193 beaker.cache.long_term.expire=36000
187 beaker.cache.long_term.key_length = 256
194 beaker.cache.long_term.key_length = 256
188
195
189 beaker.cache.sql_cache_short.type=memory
196 beaker.cache.sql_cache_short.type=memory
190 beaker.cache.sql_cache_short.expire=10
197 beaker.cache.sql_cache_short.expire=10
191 beaker.cache.sql_cache_short.key_length = 256
198 beaker.cache.sql_cache_short.key_length = 256
192
199
193 beaker.cache.sql_cache_med.type=memory
200 beaker.cache.sql_cache_med.type=memory
194 beaker.cache.sql_cache_med.expire=360
201 beaker.cache.sql_cache_med.expire=360
195 beaker.cache.sql_cache_med.key_length = 256
202 beaker.cache.sql_cache_med.key_length = 256
196
203
197 beaker.cache.sql_cache_long.type=file
204 beaker.cache.sql_cache_long.type=file
198 beaker.cache.sql_cache_long.expire=3600
205 beaker.cache.sql_cache_long.expire=3600
199 beaker.cache.sql_cache_long.key_length = 256
206 beaker.cache.sql_cache_long.key_length = 256
200
207
201 ####################################
208 ####################################
202 ### BEAKER SESSION ####
209 ### BEAKER SESSION ####
203 ####################################
210 ####################################
204 ## Type of storage used for the session, current types are
211 ## Type of storage used for the session, current types are
205 ## dbm, file, memcached, database, and memory.
212 ## dbm, file, memcached, database, and memory.
206 ## The storage uses the Container API
213 ## The storage uses the Container API
207 ## that is also used by the cache system.
214 ## that is also used by the cache system.
208
215
209 ## db session ##
216 ## db session ##
210 #beaker.session.type = ext:database
217 #beaker.session.type = ext:database
211 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
218 #beaker.session.sa.url = postgresql://postgres:qwe@localhost/rhodecode
212 #beaker.session.table_name = db_session
219 #beaker.session.table_name = db_session
213
220
214 ## encrypted cookie client side session, good for many instances ##
221 ## encrypted cookie client side session, good for many instances ##
215 #beaker.session.type = cookie
222 #beaker.session.type = cookie
216
223
217 ## file based cookies (default) ##
224 ## file based cookies (default) ##
218 #beaker.session.type = file
225 #beaker.session.type = file
219
226
220
227
221 beaker.session.key = rhodecode
228 beaker.session.key = rhodecode
222 ## secure cookie requires AES python libraries ##
229 ## secure cookie requires AES python libraries ##
223 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
230 #beaker.session.encrypt_key = g654dcno0-9873jhgfreyu
224 #beaker.session.validate_key = 9712sds2212c--zxc123
231 #beaker.session.validate_key = 9712sds2212c--zxc123
225 ## sets session as invalid if it haven't been accessed for given amount of time
232 ## sets session as invalid if it haven't been accessed for given amount of time
226 beaker.session.timeout = 2592000
233 beaker.session.timeout = 2592000
227 beaker.session.httponly = true
234 beaker.session.httponly = true
228 #beaker.session.cookie_path = /<your-prefix>
235 #beaker.session.cookie_path = /<your-prefix>
229
236
230 ## uncomment for https secure cookie ##
237 ## uncomment for https secure cookie ##
231 beaker.session.secure = false
238 beaker.session.secure = false
232
239
233 ## auto save the session to not to use .save() ##
240 ## auto save the session to not to use .save() ##
234 beaker.session.auto = False
241 beaker.session.auto = False
235
242
236 ## default cookie expiration time in seconds `true` expire at browser close ##
243 ## default cookie expiration time in seconds `true` expire at browser close ##
237 #beaker.session.cookie_expires = 3600
244 #beaker.session.cookie_expires = 3600
238
245
239
246
240 ############################
247 ############################
241 ## ERROR HANDLING SYSTEMS ##
248 ## ERROR HANDLING SYSTEMS ##
242 ############################
249 ############################
243
250
244 ####################
251 ####################
245 ### [errormator] ###
252 ### [errormator] ###
246 ####################
253 ####################
247
254
248 # Errormator is tailored to work with RhodeCode, see
255 # Errormator is tailored to work with RhodeCode, see
249 # http://errormator.com for details how to obtain an account
256 # http://errormator.com for details how to obtain an account
250 # you must install python package `errormator_client` to make it work
257 # you must install python package `errormator_client` to make it work
251
258
252 # errormator enabled
259 # errormator enabled
253 errormator = true
260 errormator = true
254
261
255 errormator.server_url = https://api.errormator.com
262 errormator.server_url = https://api.errormator.com
256 errormator.api_key = YOUR_API_KEY
263 errormator.api_key = YOUR_API_KEY
257
264
258 # TWEAK AMOUNT OF INFO SENT HERE
265 # TWEAK AMOUNT OF INFO SENT HERE
259
266
260 # enables 404 error logging (default False)
267 # enables 404 error logging (default False)
261 errormator.report_404 = false
268 errormator.report_404 = false
262
269
263 # time in seconds after request is considered being slow (default 1)
270 # time in seconds after request is considered being slow (default 1)
264 errormator.slow_request_time = 1
271 errormator.slow_request_time = 1
265
272
266 # record slow requests in application
273 # record slow requests in application
267 # (needs to be enabled for slow datastore recording and time tracking)
274 # (needs to be enabled for slow datastore recording and time tracking)
268 errormator.slow_requests = true
275 errormator.slow_requests = true
269
276
270 # enable hooking to application loggers
277 # enable hooking to application loggers
271 # errormator.logging = true
278 # errormator.logging = true
272
279
273 # minimum log level for log capture
280 # minimum log level for log capture
274 # errormator.logging.level = WARNING
281 # errormator.logging.level = WARNING
275
282
276 # send logs only from erroneous/slow requests
283 # send logs only from erroneous/slow requests
277 # (saves API quota for intensive logging)
284 # (saves API quota for intensive logging)
278 errormator.logging_on_error = false
285 errormator.logging_on_error = false
279
286
280 # list of additonal keywords that should be grabbed from environ object
287 # list of additonal keywords that should be grabbed from environ object
281 # can be string with comma separated list of words in lowercase
288 # can be string with comma separated list of words in lowercase
282 # (by default client will always send following info:
289 # (by default client will always send following info:
283 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
290 # 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that
284 # start with HTTP* this list be extended with additional keywords here
291 # start with HTTP* this list be extended with additional keywords here
285 errormator.environ_keys_whitelist =
292 errormator.environ_keys_whitelist =
286
293
287
294
288 # list of keywords that should be blanked from request object
295 # list of keywords that should be blanked from request object
289 # can be string with comma separated list of words in lowercase
296 # can be string with comma separated list of words in lowercase
290 # (by default client will always blank keys that contain following words
297 # (by default client will always blank keys that contain following words
291 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
298 # 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf'
292 # this list be extended with additional keywords set here
299 # this list be extended with additional keywords set here
293 errormator.request_keys_blacklist =
300 errormator.request_keys_blacklist =
294
301
295
302
296 # list of namespaces that should be ignores when gathering log entries
303 # list of namespaces that should be ignores when gathering log entries
297 # can be string with comma separated list of namespaces
304 # can be string with comma separated list of namespaces
298 # (by default the client ignores own entries: errormator_client.client)
305 # (by default the client ignores own entries: errormator_client.client)
299 errormator.log_namespace_blacklist =
306 errormator.log_namespace_blacklist =
300
307
301
308
302 ################
309 ################
303 ### [sentry] ###
310 ### [sentry] ###
304 ################
311 ################
305
312
306 # sentry is a alternative open source error aggregator
313 # sentry is a alternative open source error aggregator
307 # you must install python packages `sentry` and `raven` to enable
314 # you must install python packages `sentry` and `raven` to enable
308
315
309 sentry.dsn = YOUR_DNS
316 sentry.dsn = YOUR_DNS
310 sentry.servers =
317 sentry.servers =
311 sentry.name =
318 sentry.name =
312 sentry.key =
319 sentry.key =
313 sentry.public_key =
320 sentry.public_key =
314 sentry.secret_key =
321 sentry.secret_key =
315 sentry.project =
322 sentry.project =
316 sentry.site =
323 sentry.site =
317 sentry.include_paths =
324 sentry.include_paths =
318 sentry.exclude_paths =
325 sentry.exclude_paths =
319
326
320
327
321 ################################################################################
328 ################################################################################
322 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
329 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
323 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
330 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
324 ## execute malicious code after an exception is raised. ##
331 ## execute malicious code after an exception is raised. ##
325 ################################################################################
332 ################################################################################
326 set debug = false
333 set debug = false
327
334
328 ##################################
335 ##################################
329 ### LOGVIEW CONFIG ###
336 ### LOGVIEW CONFIG ###
330 ##################################
337 ##################################
331 logview.sqlalchemy = #faa
338 logview.sqlalchemy = #faa
332 logview.pylons.templating = #bfb
339 logview.pylons.templating = #bfb
333 logview.pylons.util = #eee
340 logview.pylons.util = #eee
334
341
335 #########################################################
342 #########################################################
336 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
343 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
337 #########################################################
344 #########################################################
338
345
339 # SQLITE [default]
346 # SQLITE [default]
340 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
347 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
341
348
342 # POSTGRESQL
349 # POSTGRESQL
343 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
350 # sqlalchemy.db1.url = postgresql://user:pass@localhost/rhodecode
344
351
345 # MySQL
352 # MySQL
346 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
353 # sqlalchemy.db1.url = mysql://user:pass@localhost/rhodecode
347
354
348 # see sqlalchemy docs for others
355 # see sqlalchemy docs for others
349
356
350 sqlalchemy.db1.echo = false
357 sqlalchemy.db1.echo = false
351 sqlalchemy.db1.pool_recycle = 3600
358 sqlalchemy.db1.pool_recycle = 3600
352 sqlalchemy.db1.convert_unicode = true
359 sqlalchemy.db1.convert_unicode = true
353
360
354 ################################
361 ################################
355 ### LOGGING CONFIGURATION ####
362 ### LOGGING CONFIGURATION ####
356 ################################
363 ################################
357 [loggers]
364 [loggers]
358 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
365 keys = root, routes, rhodecode, sqlalchemy, beaker, templates, whoosh_indexer
359
366
360 [handlers]
367 [handlers]
361 keys = console, console_sql
368 keys = console, console_sql
362
369
363 [formatters]
370 [formatters]
364 keys = generic, color_formatter, color_formatter_sql
371 keys = generic, color_formatter, color_formatter_sql
365
372
366 #############
373 #############
367 ## LOGGERS ##
374 ## LOGGERS ##
368 #############
375 #############
369 [logger_root]
376 [logger_root]
370 level = NOTSET
377 level = NOTSET
371 handlers = console
378 handlers = console
372
379
373 [logger_routes]
380 [logger_routes]
374 level = DEBUG
381 level = DEBUG
375 handlers =
382 handlers =
376 qualname = routes.middleware
383 qualname = routes.middleware
377 # "level = DEBUG" logs the route matched and routing variables.
384 # "level = DEBUG" logs the route matched and routing variables.
378 propagate = 1
385 propagate = 1
379
386
380 [logger_beaker]
387 [logger_beaker]
381 level = DEBUG
388 level = DEBUG
382 handlers =
389 handlers =
383 qualname = beaker.container
390 qualname = beaker.container
384 propagate = 1
391 propagate = 1
385
392
386 [logger_templates]
393 [logger_templates]
387 level = INFO
394 level = INFO
388 handlers =
395 handlers =
389 qualname = pylons.templating
396 qualname = pylons.templating
390 propagate = 1
397 propagate = 1
391
398
392 [logger_rhodecode]
399 [logger_rhodecode]
393 level = DEBUG
400 level = DEBUG
394 handlers =
401 handlers =
395 qualname = rhodecode
402 qualname = rhodecode
396 propagate = 1
403 propagate = 1
397
404
398 [logger_sqlalchemy]
405 [logger_sqlalchemy]
399 level = INFO
406 level = INFO
400 handlers = console_sql
407 handlers = console_sql
401 qualname = sqlalchemy.engine
408 qualname = sqlalchemy.engine
402 propagate = 0
409 propagate = 0
403
410
404 [logger_whoosh_indexer]
411 [logger_whoosh_indexer]
405 level = DEBUG
412 level = DEBUG
406 handlers =
413 handlers =
407 qualname = whoosh_indexer
414 qualname = whoosh_indexer
408 propagate = 1
415 propagate = 1
409
416
410 ##############
417 ##############
411 ## HANDLERS ##
418 ## HANDLERS ##
412 ##############
419 ##############
413
420
414 [handler_console]
421 [handler_console]
415 class = StreamHandler
422 class = StreamHandler
416 args = (sys.stderr,)
423 args = (sys.stderr,)
417 level = INFO
424 level = INFO
418 formatter = generic
425 formatter = generic
419
426
420 [handler_console_sql]
427 [handler_console_sql]
421 class = StreamHandler
428 class = StreamHandler
422 args = (sys.stderr,)
429 args = (sys.stderr,)
423 level = WARN
430 level = WARN
424 formatter = generic
431 formatter = generic
425
432
426 ################
433 ################
427 ## FORMATTERS ##
434 ## FORMATTERS ##
428 ################
435 ################
429
436
430 [formatter_generic]
437 [formatter_generic]
431 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
438 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
432 datefmt = %Y-%m-%d %H:%M:%S
439 datefmt = %Y-%m-%d %H:%M:%S
433
440
434 [formatter_color_formatter]
441 [formatter_color_formatter]
435 class=rhodecode.lib.colored_formatter.ColorFormatter
442 class=rhodecode.lib.colored_formatter.ColorFormatter
436 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
443 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
437 datefmt = %Y-%m-%d %H:%M:%S
444 datefmt = %Y-%m-%d %H:%M:%S
438
445
439 [formatter_color_formatter_sql]
446 [formatter_color_formatter_sql]
440 class=rhodecode.lib.colored_formatter.ColorFormatterSql
447 class=rhodecode.lib.colored_formatter.ColorFormatterSql
441 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
448 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
442 datefmt = %Y-%m-%d %H:%M:%S
449 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,323 +1,324 b''
1 """The base Controller API
1 """The base Controller API
2
2
3 Provides the BaseController class for subclassing.
3 Provides the BaseController class for subclassing.
4 """
4 """
5 import logging
5 import logging
6 import time
6 import time
7 import traceback
7 import traceback
8
8
9 from paste.auth.basic import AuthBasicAuthenticator
9 from paste.auth.basic import AuthBasicAuthenticator
10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
10 from paste.httpexceptions import HTTPUnauthorized, HTTPForbidden
11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
11 from paste.httpheaders import WWW_AUTHENTICATE, AUTHORIZATION
12
12
13 from pylons import config, tmpl_context as c, request, session, url
13 from pylons import config, tmpl_context as c, request, session, url
14 from pylons.controllers import WSGIController
14 from pylons.controllers import WSGIController
15 from pylons.controllers.util import redirect
15 from pylons.controllers.util import redirect
16 from pylons.templating import render_mako as render
16 from pylons.templating import render_mako as render
17
17
18 from rhodecode import __version__, BACKENDS
18 from rhodecode import __version__, BACKENDS
19
19
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
20 from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict,\
21 safe_str
21 safe_str, safe_int
22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
22 from rhodecode.lib.auth import AuthUser, get_container_username, authfunc,\
23 HasPermissionAnyMiddleware, CookieStoreWrapper
23 HasPermissionAnyMiddleware, CookieStoreWrapper
24 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
24 from rhodecode.lib.utils import get_repo_slug, invalidate_cache
25 from rhodecode.model import meta
25 from rhodecode.model import meta
26
26
27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
27 from rhodecode.model.db import Repository, RhodeCodeUi, User, RhodeCodeSetting
28 from rhodecode.model.notification import NotificationModel
28 from rhodecode.model.notification import NotificationModel
29 from rhodecode.model.scm import ScmModel
29 from rhodecode.model.scm import ScmModel
30 from rhodecode.model.meta import Session
30 from rhodecode.model.meta import Session
31
31
32 log = logging.getLogger(__name__)
32 log = logging.getLogger(__name__)
33
33
34
34
35 def _get_ip_addr(environ):
35 def _get_ip_addr(environ):
36 proxy_key = 'HTTP_X_REAL_IP'
36 proxy_key = 'HTTP_X_REAL_IP'
37 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
37 proxy_key2 = 'HTTP_X_FORWARDED_FOR'
38 def_key = 'REMOTE_ADDR'
38 def_key = 'REMOTE_ADDR'
39
39
40 ip = environ.get(proxy_key2)
40 ip = environ.get(proxy_key2)
41 if ip:
41 if ip:
42 return ip
42 return ip
43
43
44 ip = environ.get(proxy_key)
44 ip = environ.get(proxy_key)
45
45
46 if ip:
46 if ip:
47 return ip
47 return ip
48
48
49 ip = environ.get(def_key, '0.0.0.0')
49 ip = environ.get(def_key, '0.0.0.0')
50 return ip
50 return ip
51
51
52
52
53 def _get_access_path(environ):
53 def _get_access_path(environ):
54 path = environ.get('PATH_INFO')
54 path = environ.get('PATH_INFO')
55 org_req = environ.get('pylons.original_request')
55 org_req = environ.get('pylons.original_request')
56 if org_req:
56 if org_req:
57 path = org_req.environ.get('PATH_INFO')
57 path = org_req.environ.get('PATH_INFO')
58 return path
58 return path
59
59
60
60
61 class BasicAuth(AuthBasicAuthenticator):
61 class BasicAuth(AuthBasicAuthenticator):
62
62
63 def __init__(self, realm, authfunc, auth_http_code=None):
63 def __init__(self, realm, authfunc, auth_http_code=None):
64 self.realm = realm
64 self.realm = realm
65 self.authfunc = authfunc
65 self.authfunc = authfunc
66 self._rc_auth_http_code = auth_http_code
66 self._rc_auth_http_code = auth_http_code
67
67
68 def build_authentication(self):
68 def build_authentication(self):
69 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
69 head = WWW_AUTHENTICATE.tuples('Basic realm="%s"' % self.realm)
70 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
70 if self._rc_auth_http_code and self._rc_auth_http_code == '403':
71 # return 403 if alternative http return code is specified in
71 # return 403 if alternative http return code is specified in
72 # RhodeCode config
72 # RhodeCode config
73 return HTTPForbidden(headers=head)
73 return HTTPForbidden(headers=head)
74 return HTTPUnauthorized(headers=head)
74 return HTTPUnauthorized(headers=head)
75
75
76 def authenticate(self, environ):
76 def authenticate(self, environ):
77 authorization = AUTHORIZATION(environ)
77 authorization = AUTHORIZATION(environ)
78 if not authorization:
78 if not authorization:
79 return self.build_authentication()
79 return self.build_authentication()
80 (authmeth, auth) = authorization.split(' ', 1)
80 (authmeth, auth) = authorization.split(' ', 1)
81 if 'basic' != authmeth.lower():
81 if 'basic' != authmeth.lower():
82 return self.build_authentication()
82 return self.build_authentication()
83 auth = auth.strip().decode('base64')
83 auth = auth.strip().decode('base64')
84 _parts = auth.split(':', 1)
84 _parts = auth.split(':', 1)
85 if len(_parts) == 2:
85 if len(_parts) == 2:
86 username, password = _parts
86 username, password = _parts
87 if self.authfunc(environ, username, password):
87 if self.authfunc(environ, username, password):
88 return username
88 return username
89 return self.build_authentication()
89 return self.build_authentication()
90
90
91 __call__ = authenticate
91 __call__ = authenticate
92
92
93
93
94 class BaseVCSController(object):
94 class BaseVCSController(object):
95
95
96 def __init__(self, application, config):
96 def __init__(self, application, config):
97 self.application = application
97 self.application = application
98 self.config = config
98 self.config = config
99 # base path of repo locations
99 # base path of repo locations
100 self.basepath = self.config['base_path']
100 self.basepath = self.config['base_path']
101 #authenticate this mercurial request using authfunc
101 #authenticate this mercurial request using authfunc
102 self.authenticate = BasicAuth('', authfunc,
102 self.authenticate = BasicAuth('', authfunc,
103 config.get('auth_ret_code'))
103 config.get('auth_ret_code'))
104 self.ipaddr = '0.0.0.0'
104 self.ipaddr = '0.0.0.0'
105
105
106 def _handle_request(self, environ, start_response):
106 def _handle_request(self, environ, start_response):
107 raise NotImplementedError()
107 raise NotImplementedError()
108
108
109 def _get_by_id(self, repo_name):
109 def _get_by_id(self, repo_name):
110 """
110 """
111 Get's a special pattern _<ID> from clone url and tries to replace it
111 Get's a special pattern _<ID> from clone url and tries to replace it
112 with a repository_name for support of _<ID> non changable urls
112 with a repository_name for support of _<ID> non changable urls
113
113
114 :param repo_name:
114 :param repo_name:
115 """
115 """
116 try:
116 try:
117 data = repo_name.split('/')
117 data = repo_name.split('/')
118 if len(data) >= 2:
118 if len(data) >= 2:
119 by_id = data[1].split('_')
119 by_id = data[1].split('_')
120 if len(by_id) == 2 and by_id[1].isdigit():
120 if len(by_id) == 2 and by_id[1].isdigit():
121 _repo_name = Repository.get(by_id[1]).repo_name
121 _repo_name = Repository.get(by_id[1]).repo_name
122 data[1] = _repo_name
122 data[1] = _repo_name
123 except:
123 except:
124 log.debug('Failed to extract repo_name from id %s' % (
124 log.debug('Failed to extract repo_name from id %s' % (
125 traceback.format_exc()
125 traceback.format_exc()
126 )
126 )
127 )
127 )
128
128
129 return '/'.join(data)
129 return '/'.join(data)
130
130
131 def _invalidate_cache(self, repo_name):
131 def _invalidate_cache(self, repo_name):
132 """
132 """
133 Set's cache for this repository for invalidation on next access
133 Set's cache for this repository for invalidation on next access
134
134
135 :param repo_name: full repo name, also a cache key
135 :param repo_name: full repo name, also a cache key
136 """
136 """
137 invalidate_cache('get_repo_cached_%s' % repo_name)
137 invalidate_cache('get_repo_cached_%s' % repo_name)
138
138
139 def _check_permission(self, action, user, repo_name):
139 def _check_permission(self, action, user, repo_name):
140 """
140 """
141 Checks permissions using action (push/pull) user and repository
141 Checks permissions using action (push/pull) user and repository
142 name
142 name
143
143
144 :param action: push or pull action
144 :param action: push or pull action
145 :param user: user instance
145 :param user: user instance
146 :param repo_name: repository name
146 :param repo_name: repository name
147 """
147 """
148 if action == 'push':
148 if action == 'push':
149 if not HasPermissionAnyMiddleware('repository.write',
149 if not HasPermissionAnyMiddleware('repository.write',
150 'repository.admin')(user,
150 'repository.admin')(user,
151 repo_name):
151 repo_name):
152 return False
152 return False
153
153
154 else:
154 else:
155 #any other action need at least read permission
155 #any other action need at least read permission
156 if not HasPermissionAnyMiddleware('repository.read',
156 if not HasPermissionAnyMiddleware('repository.read',
157 'repository.write',
157 'repository.write',
158 'repository.admin')(user,
158 'repository.admin')(user,
159 repo_name):
159 repo_name):
160 return False
160 return False
161
161
162 return True
162 return True
163
163
164 def _get_ip_addr(self, environ):
164 def _get_ip_addr(self, environ):
165 return _get_ip_addr(environ)
165 return _get_ip_addr(environ)
166
166
167 def _check_ssl(self, environ, start_response):
167 def _check_ssl(self, environ, start_response):
168 """
168 """
169 Checks the SSL check flag and returns False if SSL is not present
169 Checks the SSL check flag and returns False if SSL is not present
170 and required True otherwise
170 and required True otherwise
171 """
171 """
172 org_proto = environ['wsgi._org_proto']
172 org_proto = environ['wsgi._org_proto']
173 #check if we have SSL required ! if not it's a bad request !
173 #check if we have SSL required ! if not it's a bad request !
174 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
174 require_ssl = str2bool(RhodeCodeUi.get_by_key('push_ssl').ui_value)
175 if require_ssl and org_proto == 'http':
175 if require_ssl and org_proto == 'http':
176 log.debug('proto is %s and SSL is required BAD REQUEST !'
176 log.debug('proto is %s and SSL is required BAD REQUEST !'
177 % org_proto)
177 % org_proto)
178 return False
178 return False
179 return True
179 return True
180
180
181 def _check_locking_state(self, environ, action, repo, user_id):
181 def _check_locking_state(self, environ, action, repo, user_id):
182 """
182 """
183 Checks locking on this repository, if locking is enabled and lock is
183 Checks locking on this repository, if locking is enabled and lock is
184 present returns a tuple of make_lock, locked, locked_by.
184 present returns a tuple of make_lock, locked, locked_by.
185 make_lock can have 3 states None (do nothing) True, make lock
185 make_lock can have 3 states None (do nothing) True, make lock
186 False release lock, This value is later propagated to hooks, which
186 False release lock, This value is later propagated to hooks, which
187 do the locking. Think about this as signals passed to hooks what to do.
187 do the locking. Think about this as signals passed to hooks what to do.
188
188
189 """
189 """
190 locked = False # defines that locked error should be thrown to user
190 locked = False # defines that locked error should be thrown to user
191 make_lock = None
191 make_lock = None
192 repo = Repository.get_by_repo_name(repo)
192 repo = Repository.get_by_repo_name(repo)
193 user = User.get(user_id)
193 user = User.get(user_id)
194
194
195 # this is kind of hacky, but due to how mercurial handles client-server
195 # this is kind of hacky, but due to how mercurial handles client-server
196 # server see all operation on changeset; bookmarks, phases and
196 # server see all operation on changeset; bookmarks, phases and
197 # obsolescence marker in different transaction, we don't want to check
197 # obsolescence marker in different transaction, we don't want to check
198 # locking on those
198 # locking on those
199 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
199 obsolete_call = environ['QUERY_STRING'] in ['cmd=listkeys',]
200 locked_by = repo.locked
200 locked_by = repo.locked
201 if repo and repo.enable_locking and not obsolete_call:
201 if repo and repo.enable_locking and not obsolete_call:
202 if action == 'push':
202 if action == 'push':
203 #check if it's already locked !, if it is compare users
203 #check if it's already locked !, if it is compare users
204 user_id, _date = repo.locked
204 user_id, _date = repo.locked
205 if user.user_id == user_id:
205 if user.user_id == user_id:
206 log.debug('Got push from user %s, now unlocking' % (user))
206 log.debug('Got push from user %s, now unlocking' % (user))
207 # unlock if we have push from user who locked
207 # unlock if we have push from user who locked
208 make_lock = False
208 make_lock = False
209 else:
209 else:
210 # we're not the same user who locked, ban with 423 !
210 # we're not the same user who locked, ban with 423 !
211 locked = True
211 locked = True
212 if action == 'pull':
212 if action == 'pull':
213 if repo.locked[0] and repo.locked[1]:
213 if repo.locked[0] and repo.locked[1]:
214 locked = True
214 locked = True
215 else:
215 else:
216 log.debug('Setting lock on repo %s by %s' % (repo, user))
216 log.debug('Setting lock on repo %s by %s' % (repo, user))
217 make_lock = True
217 make_lock = True
218
218
219 else:
219 else:
220 log.debug('Repository %s do not have locking enabled' % (repo))
220 log.debug('Repository %s do not have locking enabled' % (repo))
221 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
221 log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s'
222 % (make_lock, locked, locked_by))
222 % (make_lock, locked, locked_by))
223 return make_lock, locked, locked_by
223 return make_lock, locked, locked_by
224
224
225 def __call__(self, environ, start_response):
225 def __call__(self, environ, start_response):
226 start = time.time()
226 start = time.time()
227 try:
227 try:
228 return self._handle_request(environ, start_response)
228 return self._handle_request(environ, start_response)
229 finally:
229 finally:
230 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
230 log = logging.getLogger('rhodecode.' + self.__class__.__name__)
231 log.debug('Request time: %.3fs' % (time.time() - start))
231 log.debug('Request time: %.3fs' % (time.time() - start))
232 meta.Session.remove()
232 meta.Session.remove()
233
233
234
234
235 class BaseController(WSGIController):
235 class BaseController(WSGIController):
236
236
237 def __before__(self):
237 def __before__(self):
238 c.rhodecode_version = __version__
238 c.rhodecode_version = __version__
239 c.rhodecode_instanceid = config.get('instance_id')
239 c.rhodecode_instanceid = config.get('instance_id')
240 c.rhodecode_name = config.get('rhodecode_title')
240 c.rhodecode_name = config.get('rhodecode_title')
241 c.use_gravatar = str2bool(config.get('use_gravatar'))
241 c.use_gravatar = str2bool(config.get('use_gravatar'))
242 c.ga_code = config.get('rhodecode_ga_code')
242 c.ga_code = config.get('rhodecode_ga_code')
243 # Visual options
243 # Visual options
244 c.visual = AttributeDict({})
244 c.visual = AttributeDict({})
245 rc_config = RhodeCodeSetting.get_app_settings()
245 rc_config = RhodeCodeSetting.get_app_settings()
246
246
247 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
247 c.visual.show_public_icon = str2bool(rc_config.get('rhodecode_show_public_icon'))
248 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
248 c.visual.show_private_icon = str2bool(rc_config.get('rhodecode_show_private_icon'))
249 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
249 c.visual.stylify_metatags = str2bool(rc_config.get('rhodecode_stylify_metatags'))
250 c.visual.lightweight_dashboard = str2bool(rc_config.get('rhodecode_lightweight_dashboard'))
250 c.visual.lightweight_dashboard = str2bool(rc_config.get('rhodecode_lightweight_dashboard'))
251 c.visual.lightweight_dashboard_items = safe_int(config.get('dashboard_items', 100))
251
252
252 c.repo_name = get_repo_slug(request)
253 c.repo_name = get_repo_slug(request)
253 c.backends = BACKENDS.keys()
254 c.backends = BACKENDS.keys()
254 c.unread_notifications = NotificationModel()\
255 c.unread_notifications = NotificationModel()\
255 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
256 .get_unread_cnt_for_user(c.rhodecode_user.user_id)
256 self.cut_off_limit = int(config.get('cut_off_limit'))
257 self.cut_off_limit = int(config.get('cut_off_limit'))
257
258
258 self.sa = meta.Session
259 self.sa = meta.Session
259 self.scm_model = ScmModel(self.sa)
260 self.scm_model = ScmModel(self.sa)
260 self.ip_addr = ''
261 self.ip_addr = ''
261
262
262 def __call__(self, environ, start_response):
263 def __call__(self, environ, start_response):
263 """Invoke the Controller"""
264 """Invoke the Controller"""
264 # WSGIController.__call__ dispatches to the Controller method
265 # WSGIController.__call__ dispatches to the Controller method
265 # the request is routed to. This routing information is
266 # the request is routed to. This routing information is
266 # available in environ['pylons.routes_dict']
267 # available in environ['pylons.routes_dict']
267 start = time.time()
268 start = time.time()
268 try:
269 try:
269 self.ip_addr = _get_ip_addr(environ)
270 self.ip_addr = _get_ip_addr(environ)
270 # make sure that we update permissions each time we call controller
271 # make sure that we update permissions each time we call controller
271 api_key = request.GET.get('api_key')
272 api_key = request.GET.get('api_key')
272 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
273 cookie_store = CookieStoreWrapper(session.get('rhodecode_user'))
273 user_id = cookie_store.get('user_id', None)
274 user_id = cookie_store.get('user_id', None)
274 username = get_container_username(environ, config)
275 username = get_container_username(environ, config)
275 auth_user = AuthUser(user_id, api_key, username)
276 auth_user = AuthUser(user_id, api_key, username)
276 request.user = auth_user
277 request.user = auth_user
277 self.rhodecode_user = c.rhodecode_user = auth_user
278 self.rhodecode_user = c.rhodecode_user = auth_user
278 if not self.rhodecode_user.is_authenticated and \
279 if not self.rhodecode_user.is_authenticated and \
279 self.rhodecode_user.user_id is not None:
280 self.rhodecode_user.user_id is not None:
280 self.rhodecode_user.set_authenticated(
281 self.rhodecode_user.set_authenticated(
281 cookie_store.get('is_authenticated')
282 cookie_store.get('is_authenticated')
282 )
283 )
283 log.info('IP: %s User: %s accessed %s' % (
284 log.info('IP: %s User: %s accessed %s' % (
284 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
285 self.ip_addr, auth_user, safe_unicode(_get_access_path(environ)))
285 )
286 )
286 return WSGIController.__call__(self, environ, start_response)
287 return WSGIController.__call__(self, environ, start_response)
287 finally:
288 finally:
288 log.info('IP: %s Request to %s time: %.3fs' % (
289 log.info('IP: %s Request to %s time: %.3fs' % (
289 _get_ip_addr(environ),
290 _get_ip_addr(environ),
290 safe_unicode(_get_access_path(environ)), time.time() - start)
291 safe_unicode(_get_access_path(environ)), time.time() - start)
291 )
292 )
292 meta.Session.remove()
293 meta.Session.remove()
293
294
294
295
295 class BaseRepoController(BaseController):
296 class BaseRepoController(BaseController):
296 """
297 """
297 Base class for controllers responsible for loading all needed data for
298 Base class for controllers responsible for loading all needed data for
298 repository loaded items are
299 repository loaded items are
299
300
300 c.rhodecode_repo: instance of scm repository
301 c.rhodecode_repo: instance of scm repository
301 c.rhodecode_db_repo: instance of db
302 c.rhodecode_db_repo: instance of db
302 c.repository_followers: number of followers
303 c.repository_followers: number of followers
303 c.repository_forks: number of forks
304 c.repository_forks: number of forks
304 """
305 """
305
306
306 def __before__(self):
307 def __before__(self):
307 super(BaseRepoController, self).__before__()
308 super(BaseRepoController, self).__before__()
308 if c.repo_name:
309 if c.repo_name:
309
310
310 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
311 dbr = c.rhodecode_db_repo = Repository.get_by_repo_name(c.repo_name)
311 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
312 c.rhodecode_repo = c.rhodecode_db_repo.scm_instance
312 # update last change according to VCS data
313 # update last change according to VCS data
313 dbr.update_last_change(c.rhodecode_repo.last_change)
314 dbr.update_last_change(c.rhodecode_repo.last_change)
314 if c.rhodecode_repo is None:
315 if c.rhodecode_repo is None:
315 log.error('%s this repository is present in database but it '
316 log.error('%s this repository is present in database but it '
316 'cannot be created as an scm instance', c.repo_name)
317 'cannot be created as an scm instance', c.repo_name)
317
318
318 redirect(url('home'))
319 redirect(url('home'))
319
320
320 # some globals counter for menu
321 # some globals counter for menu
321 c.repository_followers = self.scm_model.get_followers(dbr)
322 c.repository_followers = self.scm_model.get_followers(dbr)
322 c.repository_forks = self.scm_model.get_forks(dbr)
323 c.repository_forks = self.scm_model.get_forks(dbr)
323 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
324 c.repository_pull_requests = self.scm_model.get_pull_requests(dbr)
@@ -1,331 +1,331 b''
1 <%page args="parent" />
1 <%page args="parent" />
2 <div class="box">
2 <div class="box">
3 <!-- box / title -->
3 <!-- box / title -->
4 <div class="title">
4 <div class="title">
5 <h5>
5 <h5>
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
6 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/> ${parent.breadcrumbs()} <span id="repo_count">0</span> ${_('repositories')}
7 </h5>
7 </h5>
8 %if c.rhodecode_user.username != 'default':
8 %if c.rhodecode_user.username != 'default':
9 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
9 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
10 <ul class="links">
10 <ul class="links">
11 <li>
11 <li>
12 %if c.group:
12 %if c.group:
13 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span>
13 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository',parent_group=c.group.group_id))}</span>
14 %else:
14 %else:
15 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
15 <span>${h.link_to(_('ADD REPOSITORY'),h.url('admin_settings_create_repository'))}</span>
16 %endif
16 %endif
17 </li>
17 </li>
18 </ul>
18 </ul>
19 %endif
19 %endif
20 %endif
20 %endif
21 </div>
21 </div>
22 <!-- end box / title -->
22 <!-- end box / title -->
23 <div class="table">
23 <div class="table">
24 % if c.groups:
24 % if c.groups:
25 <div id='groups_list_wrap' class="yui-skin-sam">
25 <div id='groups_list_wrap' class="yui-skin-sam">
26 <table id="groups_list">
26 <table id="groups_list">
27 <thead>
27 <thead>
28 <tr>
28 <tr>
29 <th class="left"><a href="#">${_('Group name')}</a></th>
29 <th class="left"><a href="#">${_('Group name')}</a></th>
30 <th class="left"><a href="#">${_('Description')}</a></th>
30 <th class="left"><a href="#">${_('Description')}</a></th>
31 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
31 ##<th class="left"><a href="#">${_('Number of repositories')}</a></th>
32 </tr>
32 </tr>
33 </thead>
33 </thead>
34
34
35 ## REPO GROUPS
35 ## REPO GROUPS
36 % for gr in c.groups:
36 % for gr in c.groups:
37 <tr>
37 <tr>
38 <td>
38 <td>
39 <div style="white-space: nowrap">
39 <div style="white-space: nowrap">
40 <img class="icon" alt="${_('Repositories group')}" src="${h.url('/images/icons/database_link.png')}"/>
40 <img class="icon" alt="${_('Repositories group')}" src="${h.url('/images/icons/database_link.png')}"/>
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
41 ${h.link_to(gr.name,url('repos_group_home',group_name=gr.group_name))}
42 </div>
42 </div>
43 </td>
43 </td>
44 %if c.visual.stylify_metatags:
44 %if c.visual.stylify_metatags:
45 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
45 <td>${h.urlify_text(h.desc_stylize(gr.group_description))}</td>
46 %else:
46 %else:
47 <td>${gr.group_description}</td>
47 <td>${gr.group_description}</td>
48 %endif
48 %endif
49 ## this is commented out since for multi nested repos can be HEAVY!
49 ## this is commented out since for multi nested repos can be HEAVY!
50 ## in number of executed queries during traversing uncomment at will
50 ## in number of executed queries during traversing uncomment at will
51 ##<td><b>${gr.repositories_recursive_count}</b></td>
51 ##<td><b>${gr.repositories_recursive_count}</b></td>
52 </tr>
52 </tr>
53 % endfor
53 % endfor
54
54
55 </table>
55 </table>
56 </div>
56 </div>
57 <div style="height: 20px"></div>
57 <div style="height: 20px"></div>
58 % endif
58 % endif
59 <div id="welcome" style="display:none;text-align:center">
59 <div id="welcome" style="display:none;text-align:center">
60 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
60 <h1><a href="${h.url('home')}">${c.rhodecode_name} ${c.rhodecode_version}</a></h1>
61 </div>
61 </div>
62 <%cnt=0%>
62 <%cnt=0%>
63 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
63 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
64 % if c.visual.lightweight_dashboard is False:
64 % if c.visual.lightweight_dashboard is False:
65 ## old full detailed version
65 ## old full detailed version
66 <div id='repos_list_wrap' class="yui-skin-sam">
66 <div id='repos_list_wrap' class="yui-skin-sam">
67 <table id="repos_list">
67 <table id="repos_list">
68 <thead>
68 <thead>
69 <tr>
69 <tr>
70 <th class="left"></th>
70 <th class="left"></th>
71 <th class="left">${_('Name')}</th>
71 <th class="left">${_('Name')}</th>
72 <th class="left">${_('Description')}</th>
72 <th class="left">${_('Description')}</th>
73 <th class="left">${_('Last change')}</th>
73 <th class="left">${_('Last change')}</th>
74 <th class="left">${_('Tip')}</th>
74 <th class="left">${_('Tip')}</th>
75 <th class="left">${_('Owner')}</th>
75 <th class="left">${_('Owner')}</th>
76 <th class="left">${_('RSS')}</th>
76 <th class="left">${_('RSS')}</th>
77 <th class="left">${_('Atom')}</th>
77 <th class="left">${_('Atom')}</th>
78 </tr>
78 </tr>
79 </thead>
79 </thead>
80 <tbody>
80 <tbody>
81 %for cnt,repo in enumerate(c.repos_list):
81 %for cnt,repo in enumerate(c.repos_list):
82 <tr class="parity${(cnt+1)%2}">
82 <tr class="parity${(cnt+1)%2}">
83 ##QUICK MENU
83 ##QUICK MENU
84 <td class="quick_repo_menu">
84 <td class="quick_repo_menu">
85 ${dt.quick_menu(repo['name'])}
85 ${dt.quick_menu(repo['name'])}
86 </td>
86 </td>
87 ##REPO NAME AND ICONS
87 ##REPO NAME AND ICONS
88 <td class="reponame">
88 <td class="reponame">
89 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']),pageargs.get('short_repo_names'))}
89 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],h.AttributeDict(repo['dbrepo_fork']),pageargs.get('short_repo_names'))}
90 </td>
90 </td>
91 ##DESCRIPTION
91 ##DESCRIPTION
92 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
92 <td><span class="tooltip" title="${h.tooltip(repo['description'])}">
93 %if c.visual.stylify_metatags:
93 %if c.visual.stylify_metatags:
94 ${h.urlify_text(h.desc_stylize(h.truncate(repo['description'],60)))}</span>
94 ${h.urlify_text(h.desc_stylize(h.truncate(repo['description'],60)))}</span>
95 %else:
95 %else:
96 ${h.truncate(repo['description'],60)}</span>
96 ${h.truncate(repo['description'],60)}</span>
97 %endif
97 %endif
98 </td>
98 </td>
99 ##LAST CHANGE DATE
99 ##LAST CHANGE DATE
100 <td>
100 <td>
101 ${dt.last_change(repo['last_change'])}
101 ${dt.last_change(repo['last_change'])}
102 </td>
102 </td>
103 ##LAST REVISION
103 ##LAST REVISION
104 <td>
104 <td>
105 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
105 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
106 </td>
106 </td>
107 ##
107 ##
108 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
108 <td title="${repo['contact']}">${h.person(repo['contact'])}</td>
109 <td>
109 <td>
110 ${dt.rss(repo['name'])}
110 ${dt.rss(repo['name'])}
111 </td>
111 </td>
112 <td>
112 <td>
113 ${dt.atom(repo['name'])}
113 ${dt.atom(repo['name'])}
114 </td>
114 </td>
115 </tr>
115 </tr>
116 %endfor
116 %endfor
117 </tbody>
117 </tbody>
118 </table>
118 </table>
119 </div>
119 </div>
120 % else:
120 % else:
121 ## lightweight version
121 ## lightweight version
122 <div class="yui-skin-sam" id="repos_list_wrap"></div>
122 <div class="yui-skin-sam" id="repos_list_wrap"></div>
123 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
123 <div id="user-paginator" style="padding: 0px 0px 0px 0px"></div>
124 % endif
124 % endif
125 </div>
125 </div>
126 </div>
126 </div>
127 % if c.visual.lightweight_dashboard is False:
127 % if c.visual.lightweight_dashboard is False:
128 <script>
128 <script>
129 YUD.get('repo_count').innerHTML = ${cnt+1 if cnt else 0};
129 YUD.get('repo_count').innerHTML = ${cnt+1 if cnt else 0};
130 var func = function(node){
130 var func = function(node){
131 return node.parentNode.parentNode.parentNode.parentNode;
131 return node.parentNode.parentNode.parentNode.parentNode;
132 }
132 }
133
133
134 // groups table sorting
134 // groups table sorting
135 var myColumnDefs = [
135 var myColumnDefs = [
136 {key:"name",label:"${_('Group name')}",sortable:true,
136 {key:"name",label:"${_('Group name')}",sortable:true,
137 sortOptions: { sortFunction: groupNameSort }},
137 sortOptions: { sortFunction: groupNameSort }},
138 {key:"desc",label:"${_('Description')}",sortable:true},
138 {key:"desc",label:"${_('Description')}",sortable:true},
139 ];
139 ];
140
140
141 var myDataSource = new YAHOO.util.DataSource(YUD.get("groups_list"));
141 var myDataSource = new YAHOO.util.DataSource(YUD.get("groups_list"));
142
142
143 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
143 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
144 myDataSource.responseSchema = {
144 myDataSource.responseSchema = {
145 fields: [
145 fields: [
146 {key:"name"},
146 {key:"name"},
147 {key:"desc"},
147 {key:"desc"},
148 ]
148 ]
149 };
149 };
150
150
151 var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource,{
151 var myDataTable = new YAHOO.widget.DataTable("groups_list_wrap", myColumnDefs, myDataSource,{
152 sortedBy:{key:"name",dir:"asc"},
152 sortedBy:{key:"name",dir:"asc"},
153 paginator: new YAHOO.widget.Paginator({
153 paginator: new YAHOO.widget.Paginator({
154 rowsPerPage: 5,
154 rowsPerPage: 5,
155 alwaysVisible: false,
155 alwaysVisible: false,
156 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
156 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
157 pageLinks: 5,
157 pageLinks: 5,
158 containerClass: 'pagination-wh',
158 containerClass: 'pagination-wh',
159 currentPageClass: 'pager_curpage',
159 currentPageClass: 'pager_curpage',
160 pageLinkClass: 'pager_link',
160 pageLinkClass: 'pager_link',
161 nextPageLinkLabel: '&gt;',
161 nextPageLinkLabel: '&gt;',
162 previousPageLinkLabel: '&lt;',
162 previousPageLinkLabel: '&lt;',
163 firstPageLinkLabel: '&lt;&lt;',
163 firstPageLinkLabel: '&lt;&lt;',
164 lastPageLinkLabel: '&gt;&gt;',
164 lastPageLinkLabel: '&gt;&gt;',
165 containers:['user-paginator']
165 containers:['user-paginator']
166 }),
166 }),
167 MSG_SORTASC:"${_('Click to sort ascending')}",
167 MSG_SORTASC:"${_('Click to sort ascending')}",
168 MSG_SORTDESC:"${_('Click to sort descending')}"
168 MSG_SORTDESC:"${_('Click to sort descending')}"
169 });
169 });
170
170
171 // main table sorting
171 // main table sorting
172 var myColumnDefs = [
172 var myColumnDefs = [
173 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
173 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
174 {key:"name",label:"${_('Name')}",sortable:true,
174 {key:"name",label:"${_('Name')}",sortable:true,
175 sortOptions: { sortFunction: nameSort }},
175 sortOptions: { sortFunction: nameSort }},
176 {key:"desc",label:"${_('Description')}",sortable:true},
176 {key:"desc",label:"${_('Description')}",sortable:true},
177 {key:"last_change",label:"${_('Last Change')}",sortable:true,
177 {key:"last_change",label:"${_('Last Change')}",sortable:true,
178 sortOptions: { sortFunction: ageSort }},
178 sortOptions: { sortFunction: ageSort }},
179 {key:"tip",label:"${_('Tip')}",sortable:true,
179 {key:"tip",label:"${_('Tip')}",sortable:true,
180 sortOptions: { sortFunction: revisionSort }},
180 sortOptions: { sortFunction: revisionSort }},
181 {key:"owner",label:"${_('Owner')}",sortable:true},
181 {key:"owner",label:"${_('Owner')}",sortable:true},
182 {key:"rss",label:"",sortable:false},
182 {key:"rss",label:"",sortable:false},
183 {key:"atom",label:"",sortable:false},
183 {key:"atom",label:"",sortable:false},
184 ];
184 ];
185
185
186 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
186 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
187
187
188 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
188 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
189
189
190 myDataSource.responseSchema = {
190 myDataSource.responseSchema = {
191 fields: [
191 fields: [
192 {key:"menu"},
192 {key:"menu"},
193 //{key:"raw_name"},
193 //{key:"raw_name"},
194 {key:"name"},
194 {key:"name"},
195 {key:"desc"},
195 {key:"desc"},
196 {key:"last_change"},
196 {key:"last_change"},
197 {key:"tip"},
197 {key:"tip"},
198 {key:"owner"},
198 {key:"owner"},
199 {key:"rss"},
199 {key:"rss"},
200 {key:"atom"},
200 {key:"atom"},
201 ]
201 ]
202 };
202 };
203
203
204 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
204 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
205 {
205 {
206 sortedBy:{key:"name",dir:"asc"},
206 sortedBy:{key:"name",dir:"asc"},
207 MSG_SORTASC:"${_('Click to sort ascending')}",
207 MSG_SORTASC:"${_('Click to sort ascending')}",
208 MSG_SORTDESC:"${_('Click to sort descending')}",
208 MSG_SORTDESC:"${_('Click to sort descending')}",
209 MSG_EMPTY:"${_('No records found.')}",
209 MSG_EMPTY:"${_('No records found.')}",
210 MSG_ERROR:"${_('Data error.')}",
210 MSG_ERROR:"${_('Data error.')}",
211 MSG_LOADING:"${_('Loading...')}",
211 MSG_LOADING:"${_('Loading...')}",
212 }
212 }
213 );
213 );
214 myDataTable.subscribe('postRenderEvent',function(oArgs) {
214 myDataTable.subscribe('postRenderEvent',function(oArgs) {
215 tooltip_activate();
215 tooltip_activate();
216 quick_repo_menu();
216 quick_repo_menu();
217 q_filter('q_filter',YUQ('div.table tr td a.repo_name'),func);
217 q_filter('q_filter',YUQ('div.table tr td a.repo_name'),func);
218 });
218 });
219
219
220 </script>
220 </script>
221 % else:
221 % else:
222 <script>
222 <script>
223 //var url = "${h.url('formatted_users', format='json')}";
223 //var url = "${h.url('formatted_users', format='json')}";
224 var data = ${c.data|n};
224 var data = ${c.data|n};
225 var myDataSource = new YAHOO.util.DataSource(data);
225 var myDataSource = new YAHOO.util.DataSource(data);
226 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
226 myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
227
227
228 myDataSource.responseSchema = {
228 myDataSource.responseSchema = {
229 resultsList: "records",
229 resultsList: "records",
230 fields: [
230 fields: [
231 {key:"menu"},
231 {key:"menu"},
232 {key:"raw_name"},
232 {key:"raw_name"},
233 {key:"name"},
233 {key:"name"},
234 {key:"desc"},
234 {key:"desc"},
235 {key:"last_change"},
235 {key:"last_change"},
236 {key:"owner"},
236 {key:"owner"},
237 {key:"rss"},
237 {key:"rss"},
238 {key:"atom"},
238 {key:"atom"},
239 ]
239 ]
240 };
240 };
241 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
241 myDataSource.doBeforeCallback = function(req,raw,res,cb) {
242 // This is the filter function
242 // This is the filter function
243 var data = res.results || [],
243 var data = res.results || [],
244 filtered = [],
244 filtered = [],
245 i,l;
245 i,l;
246
246
247 if (req) {
247 if (req) {
248 req = req.toLowerCase();
248 req = req.toLowerCase();
249 for (i = 0; i<data.length; i++) {
249 for (i = 0; i<data.length; i++) {
250 var pos = data[i].raw_name.toLowerCase().indexOf(req)
250 var pos = data[i].raw_name.toLowerCase().indexOf(req)
251 if (pos != -1) {
251 if (pos != -1) {
252 filtered.push(data[i]);
252 filtered.push(data[i]);
253 }
253 }
254 }
254 }
255 res.results = filtered;
255 res.results = filtered;
256 }
256 }
257 YUD.get('repo_count').innerHTML = res.results.length;
257 YUD.get('repo_count').innerHTML = res.results.length;
258 return res;
258 return res;
259 }
259 }
260
260
261 // main table sorting
261 // main table sorting
262 var myColumnDefs = [
262 var myColumnDefs = [
263 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
263 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
264 {key:"name",label:"${_('Name')}",sortable:true,
264 {key:"name",label:"${_('Name')}",sortable:true,
265 sortOptions: { sortFunction: nameSort }},
265 sortOptions: { sortFunction: nameSort }},
266 {key:"desc",label:"${_('Description')}",sortable:true},
266 {key:"desc",label:"${_('Description')}",sortable:true},
267 {key:"last_change",label:"${_('Last Change')}",sortable:true,
267 {key:"last_change",label:"${_('Last Change')}",sortable:true,
268 sortOptions: { sortFunction: ageSort }},
268 sortOptions: { sortFunction: ageSort }},
269 {key:"owner",label:"${_('Owner')}",sortable:true},
269 {key:"owner",label:"${_('Owner')}",sortable:true},
270 {key:"rss",label:"",sortable:false},
270 {key:"rss",label:"",sortable:false},
271 {key:"atom",label:"",sortable:false},
271 {key:"atom",label:"",sortable:false},
272 ];
272 ];
273
273
274 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
274 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,{
275 sortedBy:{key:"name",dir:"asc"},
275 sortedBy:{key:"name",dir:"asc"},
276 paginator: new YAHOO.widget.Paginator({
276 paginator: new YAHOO.widget.Paginator({
277 rowsPerPage: 15,
277 rowsPerPage: ${c.visual.lightweight_dashboard_items},
278 alwaysVisible: false,
278 alwaysVisible: false,
279 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
279 template : "{PreviousPageLink} {FirstPageLink} {PageLinks} {LastPageLink} {NextPageLink}",
280 pageLinks: 5,
280 pageLinks: 5,
281 containerClass: 'pagination-wh',
281 containerClass: 'pagination-wh',
282 currentPageClass: 'pager_curpage',
282 currentPageClass: 'pager_curpage',
283 pageLinkClass: 'pager_link',
283 pageLinkClass: 'pager_link',
284 nextPageLinkLabel: '&gt;',
284 nextPageLinkLabel: '&gt;',
285 previousPageLinkLabel: '&lt;',
285 previousPageLinkLabel: '&lt;',
286 firstPageLinkLabel: '&lt;&lt;',
286 firstPageLinkLabel: '&lt;&lt;',
287 lastPageLinkLabel: '&gt;&gt;',
287 lastPageLinkLabel: '&gt;&gt;',
288 containers:['user-paginator']
288 containers:['user-paginator']
289 }),
289 }),
290
290
291 MSG_SORTASC:"${_('Click to sort ascending')}",
291 MSG_SORTASC:"${_('Click to sort ascending')}",
292 MSG_SORTDESC:"${_('Click to sort descending')}",
292 MSG_SORTDESC:"${_('Click to sort descending')}",
293 MSG_EMPTY:"${_('No records found.')}",
293 MSG_EMPTY:"${_('No records found.')}",
294 MSG_ERROR:"${_('Data error.')}",
294 MSG_ERROR:"${_('Data error.')}",
295 MSG_LOADING:"${_('Loading...')}",
295 MSG_LOADING:"${_('Loading...')}",
296 }
296 }
297 );
297 );
298 myDataTable.subscribe('postRenderEvent',function(oArgs) {
298 myDataTable.subscribe('postRenderEvent',function(oArgs) {
299 tooltip_activate();
299 tooltip_activate();
300 quick_repo_menu();
300 quick_repo_menu();
301 });
301 });
302
302
303 var filterTimeout = null;
303 var filterTimeout = null;
304
304
305 updateFilter = function () {
305 updateFilter = function () {
306 // Reset timeout
306 // Reset timeout
307 filterTimeout = null;
307 filterTimeout = null;
308
308
309 // Reset sort
309 // Reset sort
310 var state = myDataTable.getState();
310 var state = myDataTable.getState();
311 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
311 state.sortedBy = {key:'name', dir:YAHOO.widget.DataTable.CLASS_ASC};
312
312
313 // Get filtered data
313 // Get filtered data
314 myDataSource.sendRequest(YUD.get('q_filter').value,{
314 myDataSource.sendRequest(YUD.get('q_filter').value,{
315 success : myDataTable.onDataReturnInitializeTable,
315 success : myDataTable.onDataReturnInitializeTable,
316 failure : myDataTable.onDataReturnInitializeTable,
316 failure : myDataTable.onDataReturnInitializeTable,
317 scope : myDataTable,
317 scope : myDataTable,
318 argument: state
318 argument: state
319 });
319 });
320
320
321 };
321 };
322 YUE.on('q_filter','click',function(){
322 YUE.on('q_filter','click',function(){
323 YUD.get('q_filter').value = '';
323 YUD.get('q_filter').value = '';
324 });
324 });
325
325
326 YUE.on('q_filter','keyup',function (e) {
326 YUE.on('q_filter','keyup',function (e) {
327 clearTimeout(filterTimeout);
327 clearTimeout(filterTimeout);
328 filterTimeout = setTimeout(updateFilter,600);
328 filterTimeout = setTimeout(updateFilter,600);
329 });
329 });
330 </script>
330 </script>
331 % endif
331 % endif
General Comments 0
You need to be logged in to leave comments. Login now