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