##// END OF EJS Templates
merge with optional gravatars
marcink -
r1115:fcb50549 merge beta
parent child Browse files
Show More
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -1,220 +1,221 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 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls = false
24 #smtp_use_tls = false
25 #smtp_use_ssl = true
25 #smtp_use_ssl = true
26
26
27 [server:main]
27 [server:main]
28 ##nr of threads to spawn
28 ##nr of threads to spawn
29 threadpool_workers = 5
29 threadpool_workers = 5
30
30
31 ##max request before thread respawn
31 ##max request before thread respawn
32 threadpool_max_requests = 6
32 threadpool_max_requests = 6
33
33
34 ##option to use threads of process
34 ##option to use threads of process
35 use_threadpool = false
35 use_threadpool = false
36
36
37 use = egg:Paste#http
37 use = egg:Paste#http
38 host = 0.0.0.0
38 host = 0.0.0.0
39 port = 5000
39 port = 5000
40
40
41 [app:main]
41 [app:main]
42 use = egg:rhodecode
42 use = egg:rhodecode
43 full_stack = true
43 full_stack = true
44 static_files = true
44 static_files = true
45 lang=en
45 lang=en
46 cache_dir = %(here)s/data
46 cache_dir = %(here)s/data
47 index_dir = %(here)s/data/index
47 index_dir = %(here)s/data/index
48 app_instance_uuid = develop
48 app_instance_uuid = develop
49 cut_off_limit = 256000
49 cut_off_limit = 256000
50 force_https = false
50 force_https = false
51 commit_parse_limit = 25
51 commit_parse_limit = 25
52 use_gravatar = true
52
53
53 ####################################
54 ####################################
54 ### CELERY CONFIG ####
55 ### CELERY CONFIG ####
55 ####################################
56 ####################################
56 use_celery = false
57 use_celery = false
57 broker.host = localhost
58 broker.host = localhost
58 broker.vhost = rabbitmqhost
59 broker.vhost = rabbitmqhost
59 broker.port = 5672
60 broker.port = 5672
60 broker.user = rabbitmq
61 broker.user = rabbitmq
61 broker.password = qweqwe
62 broker.password = qweqwe
62
63
63 celery.imports = rhodecode.lib.celerylib.tasks
64 celery.imports = rhodecode.lib.celerylib.tasks
64
65
65 celery.result.backend = amqp
66 celery.result.backend = amqp
66 celery.result.dburi = amqp://
67 celery.result.dburi = amqp://
67 celery.result.serialier = json
68 celery.result.serialier = json
68
69
69 #celery.send.task.error.emails = true
70 #celery.send.task.error.emails = true
70 #celery.amqp.task.result.expires = 18000
71 #celery.amqp.task.result.expires = 18000
71
72
72 celeryd.concurrency = 2
73 celeryd.concurrency = 2
73 #celeryd.log.file = celeryd.log
74 #celeryd.log.file = celeryd.log
74 celeryd.log.level = debug
75 celeryd.log.level = debug
75 celeryd.max.tasks.per.child = 1
76 celeryd.max.tasks.per.child = 1
76
77
77 #tasks will never be sent to the queue, but executed locally instead.
78 #tasks will never be sent to the queue, but executed locally instead.
78 celery.always.eager = false
79 celery.always.eager = false
79
80
80 ####################################
81 ####################################
81 ### BEAKER CACHE ####
82 ### BEAKER CACHE ####
82 ####################################
83 ####################################
83 beaker.cache.data_dir=%(here)s/data/cache/data
84 beaker.cache.data_dir=%(here)s/data/cache/data
84 beaker.cache.lock_dir=%(here)s/data/cache/lock
85 beaker.cache.lock_dir=%(here)s/data/cache/lock
85
86
86 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
87 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
87
88
88 beaker.cache.super_short_term.type=memory
89 beaker.cache.super_short_term.type=memory
89 beaker.cache.super_short_term.expire=10
90 beaker.cache.super_short_term.expire=10
90
91
91 beaker.cache.short_term.type=memory
92 beaker.cache.short_term.type=memory
92 beaker.cache.short_term.expire=60
93 beaker.cache.short_term.expire=60
93
94
94 beaker.cache.long_term.type=memory
95 beaker.cache.long_term.type=memory
95 beaker.cache.long_term.expire=36000
96 beaker.cache.long_term.expire=36000
96
97
97 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.expire=10
99 beaker.cache.sql_cache_short.expire=10
99
100
100 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.expire=360
102 beaker.cache.sql_cache_med.expire=360
102
103
103 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.expire=3600
105 beaker.cache.sql_cache_long.expire=3600
105
106
106 ####################################
107 ####################################
107 ### BEAKER SESSION ####
108 ### BEAKER SESSION ####
108 ####################################
109 ####################################
109 ## Type of storage used for the session, current types are
110 ## Type of storage used for the session, current types are
110 ## dbm, file, memcached, database, and memory.
111 ## dbm, file, memcached, database, and memory.
111 ## The storage uses the Container API
112 ## The storage uses the Container API
112 ##that is also used by the cache system.
113 ##that is also used by the cache system.
113 beaker.session.type = file
114 beaker.session.type = file
114
115
115 beaker.session.key = rhodecode
116 beaker.session.key = rhodecode
116 beaker.session.secret = g654dcno0-9873jhgfreyu
117 beaker.session.secret = g654dcno0-9873jhgfreyu
117 beaker.session.timeout = 36000
118 beaker.session.timeout = 36000
118
119
119 ##auto save the session to not to use .save()
120 ##auto save the session to not to use .save()
120 beaker.session.auto = False
121 beaker.session.auto = False
121
122
122 ##true exire at browser close
123 ##true exire at browser close
123 #beaker.session.cookie_expires = 3600
124 #beaker.session.cookie_expires = 3600
124
125
125
126
126 ################################################################################
127 ################################################################################
127 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## execute malicious code after an exception is raised. ##
130 ## execute malicious code after an exception is raised. ##
130 ################################################################################
131 ################################################################################
131 #set debug = false
132 #set debug = false
132
133
133 ##################################
134 ##################################
134 ### LOGVIEW CONFIG ###
135 ### LOGVIEW CONFIG ###
135 ##################################
136 ##################################
136 logview.sqlalchemy = #faa
137 logview.sqlalchemy = #faa
137 logview.pylons.templating = #bfb
138 logview.pylons.templating = #bfb
138 logview.pylons.util = #eee
139 logview.pylons.util = #eee
139
140
140 #########################################################
141 #########################################################
141 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 #########################################################
143 #########################################################
143 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
145 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
145 #sqlalchemy.db1.echo = False
146 #sqlalchemy.db1.echo = False
146 #sqlalchemy.db1.pool_recycle = 3600
147 #sqlalchemy.db1.pool_recycle = 3600
147 sqlalchemy.convert_unicode = true
148 sqlalchemy.convert_unicode = true
148
149
149 ################################
150 ################################
150 ### LOGGING CONFIGURATION ####
151 ### LOGGING CONFIGURATION ####
151 ################################
152 ################################
152 [loggers]
153 [loggers]
153 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
154 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
154
155
155 [handlers]
156 [handlers]
156 keys = console
157 keys = console
157
158
158 [formatters]
159 [formatters]
159 keys = generic,color_formatter
160 keys = generic,color_formatter
160
161
161 #############
162 #############
162 ## LOGGERS ##
163 ## LOGGERS ##
163 #############
164 #############
164 [logger_root]
165 [logger_root]
165 level = NOTSET
166 level = NOTSET
166 handlers = console
167 handlers = console
167
168
168 [logger_routes]
169 [logger_routes]
169 level = DEBUG
170 level = DEBUG
170 handlers = console
171 handlers = console
171 qualname = routes.middleware
172 qualname = routes.middleware
172 # "level = DEBUG" logs the route matched and routing variables.
173 # "level = DEBUG" logs the route matched and routing variables.
173 propagate = 0
174 propagate = 0
174
175
175 [logger_beaker]
176 [logger_beaker]
176 level = ERROR
177 level = ERROR
177 handlers = console
178 handlers = console
178 qualname = beaker.container
179 qualname = beaker.container
179 propagate = 0
180 propagate = 0
180
181
181 [logger_templates]
182 [logger_templates]
182 level = INFO
183 level = INFO
183 handlers = console
184 handlers = console
184 qualname = pylons.templating
185 qualname = pylons.templating
185 propagate = 0
186 propagate = 0
186
187
187 [logger_rhodecode]
188 [logger_rhodecode]
188 level = DEBUG
189 level = DEBUG
189 handlers = console
190 handlers = console
190 qualname = rhodecode
191 qualname = rhodecode
191 propagate = 0
192 propagate = 0
192
193
193 [logger_sqlalchemy]
194 [logger_sqlalchemy]
194 level = ERROR
195 level = ERROR
195 handlers = console
196 handlers = console
196 qualname = sqlalchemy.engine
197 qualname = sqlalchemy.engine
197 propagate = 0
198 propagate = 0
198
199
199 ##############
200 ##############
200 ## HANDLERS ##
201 ## HANDLERS ##
201 ##############
202 ##############
202
203
203 [handler_console]
204 [handler_console]
204 class = StreamHandler
205 class = StreamHandler
205 args = (sys.stderr,)
206 args = (sys.stderr,)
206 level = NOTSET
207 level = NOTSET
207 formatter = color_formatter
208 formatter = color_formatter
208
209
209 ################
210 ################
210 ## FORMATTERS ##
211 ## FORMATTERS ##
211 ################
212 ################
212
213
213 [formatter_generic]
214 [formatter_generic]
214 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
215 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
215 datefmt = %Y-%m-%d %H:%M:%S
216 datefmt = %Y-%m-%d %H:%M:%S
216
217
217 [formatter_color_formatter]
218 [formatter_color_formatter]
218 class=rhodecode.lib.colored_formatter.ColorFormatter
219 class=rhodecode.lib.colored_formatter.ColorFormatter
219 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
220 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
220 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
221 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,219 +1,220 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 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls = false
24 #smtp_use_tls = false
25 #smtp_use_ssl = true
25 #smtp_use_ssl = true
26
26
27 [server:main]
27 [server:main]
28 ##nr of threads to spawn
28 ##nr of threads to spawn
29 threadpool_workers = 5
29 threadpool_workers = 5
30
30
31 ##max request before thread respawn
31 ##max request before thread respawn
32 threadpool_max_requests = 2
32 threadpool_max_requests = 2
33
33
34 ##option to use threads of process
34 ##option to use threads of process
35 use_threadpool = true
35 use_threadpool = true
36
36
37 use = egg:Paste#http
37 use = egg:Paste#http
38 host = 127.0.0.1
38 host = 127.0.0.1
39 port = 8001
39 port = 8001
40
40
41 [app:main]
41 [app:main]
42 use = egg:rhodecode
42 use = egg:rhodecode
43 full_stack = true
43 full_stack = true
44 static_files = false
44 static_files = false
45 lang=en
45 lang=en
46 cache_dir = %(here)s/data
46 cache_dir = %(here)s/data
47 index_dir = %(here)s/data/index
47 index_dir = %(here)s/data/index
48 cut_off_limit = 256000
48 cut_off_limit = 256000
49 force_https = false
49 force_https = false
50 commit_parse_limit = 250
50 commit_parse_limit = 250
51 use_gravatar = true
51
52
52 ####################################
53 ####################################
53 ### CELERY CONFIG ####
54 ### CELERY CONFIG ####
54 ####################################
55 ####################################
55 use_celery = false
56 use_celery = false
56 broker.host = localhost
57 broker.host = localhost
57 broker.vhost = rabbitmqhost
58 broker.vhost = rabbitmqhost
58 broker.port = 5672
59 broker.port = 5672
59 broker.user = rabbitmq
60 broker.user = rabbitmq
60 broker.password = qweqwe
61 broker.password = qweqwe
61
62
62 celery.imports = rhodecode.lib.celerylib.tasks
63 celery.imports = rhodecode.lib.celerylib.tasks
63
64
64 celery.result.backend = amqp
65 celery.result.backend = amqp
65 celery.result.dburi = amqp://
66 celery.result.dburi = amqp://
66 celery.result.serialier = json
67 celery.result.serialier = json
67
68
68 #celery.send.task.error.emails = true
69 #celery.send.task.error.emails = true
69 #celery.amqp.task.result.expires = 18000
70 #celery.amqp.task.result.expires = 18000
70
71
71 celeryd.concurrency = 2
72 celeryd.concurrency = 2
72 #celeryd.log.file = celeryd.log
73 #celeryd.log.file = celeryd.log
73 celeryd.log.level = debug
74 celeryd.log.level = debug
74 celeryd.max.tasks.per.child = 1
75 celeryd.max.tasks.per.child = 1
75
76
76 #tasks will never be sent to the queue, but executed locally instead.
77 #tasks will never be sent to the queue, but executed locally instead.
77 celery.always.eager = false
78 celery.always.eager = false
78
79
79 ####################################
80 ####################################
80 ### BEAKER CACHE ####
81 ### BEAKER CACHE ####
81 ####################################
82 ####################################
82 beaker.cache.data_dir=%(here)s/data/cache/data
83 beaker.cache.data_dir=%(here)s/data/cache/data
83 beaker.cache.lock_dir=%(here)s/data/cache/lock
84 beaker.cache.lock_dir=%(here)s/data/cache/lock
84
85
85 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
86 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
86
87
87 beaker.cache.super_short_term.type=memory
88 beaker.cache.super_short_term.type=memory
88 beaker.cache.super_short_term.expire=10
89 beaker.cache.super_short_term.expire=10
89
90
90 beaker.cache.short_term.type=memory
91 beaker.cache.short_term.type=memory
91 beaker.cache.short_term.expire=60
92 beaker.cache.short_term.expire=60
92
93
93 beaker.cache.long_term.type=memory
94 beaker.cache.long_term.type=memory
94 beaker.cache.long_term.expire=36000
95 beaker.cache.long_term.expire=36000
95
96
96
97
97 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.expire=10
99 beaker.cache.sql_cache_short.expire=10
99
100
100 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.expire=360
102 beaker.cache.sql_cache_med.expire=360
102
103
103 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.expire=3600
105 beaker.cache.sql_cache_long.expire=3600
105
106
106 ####################################
107 ####################################
107 ### BEAKER SESSION ####
108 ### BEAKER SESSION ####
108 ####################################
109 ####################################
109 ## Type of storage used for the session, current types are
110 ## Type of storage used for the session, current types are
110 ## dbm, file, memcached, database, and memory.
111 ## dbm, file, memcached, database, and memory.
111 ## The storage uses the Container API
112 ## The storage uses the Container API
112 ##that is also used by the cache system.
113 ##that is also used by the cache system.
113 beaker.session.type = file
114 beaker.session.type = file
114
115
115 beaker.session.key = rhodecode
116 beaker.session.key = rhodecode
116 beaker.session.secret = g654dcno0-9873jhgfreyu
117 beaker.session.secret = g654dcno0-9873jhgfreyu
117 beaker.session.timeout = 36000
118 beaker.session.timeout = 36000
118
119
119 ##auto save the session to not to use .save()
120 ##auto save the session to not to use .save()
120 beaker.session.auto = False
121 beaker.session.auto = False
121
122
122 ##true exire at browser close
123 ##true exire at browser close
123 #beaker.session.cookie_expires = 3600
124 #beaker.session.cookie_expires = 3600
124
125
125
126
126 ################################################################################
127 ################################################################################
127 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## execute malicious code after an exception is raised. ##
130 ## execute malicious code after an exception is raised. ##
130 ################################################################################
131 ################################################################################
131 set debug = false
132 set debug = false
132
133
133 ##################################
134 ##################################
134 ### LOGVIEW CONFIG ###
135 ### LOGVIEW CONFIG ###
135 ##################################
136 ##################################
136 logview.sqlalchemy = #faa
137 logview.sqlalchemy = #faa
137 logview.pylons.templating = #bfb
138 logview.pylons.templating = #bfb
138 logview.pylons.util = #eee
139 logview.pylons.util = #eee
139
140
140 #########################################################
141 #########################################################
141 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 #########################################################
143 #########################################################
143 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 #sqlalchemy.db1.echo = False
145 #sqlalchemy.db1.echo = False
145 #sqlalchemy.db1.pool_recycle = 3600
146 #sqlalchemy.db1.pool_recycle = 3600
146 sqlalchemy.convert_unicode = true
147 sqlalchemy.convert_unicode = true
147
148
148 ################################
149 ################################
149 ### LOGGING CONFIGURATION ####
150 ### LOGGING CONFIGURATION ####
150 ################################
151 ################################
151 [loggers]
152 [loggers]
152 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
153 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
153
154
154 [handlers]
155 [handlers]
155 keys = console
156 keys = console
156
157
157 [formatters]
158 [formatters]
158 keys = generic,color_formatter
159 keys = generic,color_formatter
159
160
160 #############
161 #############
161 ## LOGGERS ##
162 ## LOGGERS ##
162 #############
163 #############
163 [logger_root]
164 [logger_root]
164 level = INFO
165 level = INFO
165 handlers = console
166 handlers = console
166
167
167 [logger_routes]
168 [logger_routes]
168 level = INFO
169 level = INFO
169 handlers = console
170 handlers = console
170 qualname = routes.middleware
171 qualname = routes.middleware
171 # "level = DEBUG" logs the route matched and routing variables.
172 # "level = DEBUG" logs the route matched and routing variables.
172 propagate = 0
173 propagate = 0
173
174
174 [logger_beaker]
175 [logger_beaker]
175 level = ERROR
176 level = ERROR
176 handlers = console
177 handlers = console
177 qualname = beaker.container
178 qualname = beaker.container
178 propagate = 0
179 propagate = 0
179
180
180 [logger_templates]
181 [logger_templates]
181 level = INFO
182 level = INFO
182 handlers = console
183 handlers = console
183 qualname = pylons.templating
184 qualname = pylons.templating
184 propagate = 0
185 propagate = 0
185
186
186 [logger_rhodecode]
187 [logger_rhodecode]
187 level = DEBUG
188 level = DEBUG
188 handlers = console
189 handlers = console
189 qualname = rhodecode
190 qualname = rhodecode
190 propagate = 0
191 propagate = 0
191
192
192 [logger_sqlalchemy]
193 [logger_sqlalchemy]
193 level = ERROR
194 level = ERROR
194 handlers = console
195 handlers = console
195 qualname = sqlalchemy.engine
196 qualname = sqlalchemy.engine
196 propagate = 0
197 propagate = 0
197
198
198 ##############
199 ##############
199 ## HANDLERS ##
200 ## HANDLERS ##
200 ##############
201 ##############
201
202
202 [handler_console]
203 [handler_console]
203 class = StreamHandler
204 class = StreamHandler
204 args = (sys.stderr,)
205 args = (sys.stderr,)
205 level = NOTSET
206 level = NOTSET
206 formatter = color_formatter
207 formatter = color_formatter
207
208
208 ################
209 ################
209 ## FORMATTERS ##
210 ## FORMATTERS ##
210 ################
211 ################
211
212
212 [formatter_generic]
213 [formatter_generic]
213 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
214 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
214 datefmt = %Y-%m-%d %H:%M:%S
215 datefmt = %Y-%m-%d %H:%M:%S
215
216
216 [formatter_color_formatter]
217 [formatter_color_formatter]
217 class=rhodecode.lib.colored_formatter.ColorFormatter
218 class=rhodecode.lib.colored_formatter.ColorFormatter
218 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
219 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
219 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
220 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,219 +1,220 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 ################################################################################
10 ################################################################################
11 ## Uncomment and replace with the address which should receive ##
11 ## Uncomment and replace with the address which should receive ##
12 ## any error reports after application crash ##
12 ## any error reports after application crash ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
13 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ################################################################################
14 ################################################################################
15 #email_to = admin@localhost
15 #email_to = admin@localhost
16 #error_email_from = paste_error@localhost
16 #error_email_from = paste_error@localhost
17 #app_email_from = rhodecode-noreply@localhost
17 #app_email_from = rhodecode-noreply@localhost
18 #error_message =
18 #error_message =
19
19
20 #smtp_server = mail.server.com
20 #smtp_server = mail.server.com
21 #smtp_username =
21 #smtp_username =
22 #smtp_password =
22 #smtp_password =
23 #smtp_port =
23 #smtp_port =
24 #smtp_use_tls = false
24 #smtp_use_tls = false
25 #smtp_use_ssl = true
25 #smtp_use_ssl = true
26
26
27 [server:main]
27 [server:main]
28 ##nr of threads to spawn
28 ##nr of threads to spawn
29 threadpool_workers = 5
29 threadpool_workers = 5
30
30
31 ##max request before thread respawn
31 ##max request before thread respawn
32 threadpool_max_requests = 10
32 threadpool_max_requests = 10
33
33
34 ##option to use threads of process
34 ##option to use threads of process
35 use_threadpool = true
35 use_threadpool = true
36
36
37 use = egg:Paste#http
37 use = egg:Paste#http
38 host = 127.0.0.1
38 host = 127.0.0.1
39 port = 5000
39 port = 5000
40
40
41 [app:main]
41 [app:main]
42 use = egg:rhodecode
42 use = egg:rhodecode
43 full_stack = true
43 full_stack = true
44 static_files = true
44 static_files = true
45 lang=en
45 lang=en
46 cache_dir = %(here)s/data
46 cache_dir = %(here)s/data
47 index_dir = %(here)s/data/index
47 index_dir = %(here)s/data/index
48 app_instance_uuid = ${app_instance_uuid}
48 app_instance_uuid = ${app_instance_uuid}
49 cut_off_limit = 256000
49 cut_off_limit = 256000
50 force_https = false
50 force_https = false
51 commit_parse_limit = 50
51 commit_parse_limit = 50
52 use_gravatar = true
52
53
53 ####################################
54 ####################################
54 ### CELERY CONFIG ####
55 ### CELERY CONFIG ####
55 ####################################
56 ####################################
56 use_celery = false
57 use_celery = false
57 broker.host = localhost
58 broker.host = localhost
58 broker.vhost = rabbitmqhost
59 broker.vhost = rabbitmqhost
59 broker.port = 5672
60 broker.port = 5672
60 broker.user = rabbitmq
61 broker.user = rabbitmq
61 broker.password = qweqwe
62 broker.password = qweqwe
62
63
63 celery.imports = rhodecode.lib.celerylib.tasks
64 celery.imports = rhodecode.lib.celerylib.tasks
64
65
65 celery.result.backend = amqp
66 celery.result.backend = amqp
66 celery.result.dburi = amqp://
67 celery.result.dburi = amqp://
67 celery.result.serialier = json
68 celery.result.serialier = json
68
69
69 #celery.send.task.error.emails = true
70 #celery.send.task.error.emails = true
70 #celery.amqp.task.result.expires = 18000
71 #celery.amqp.task.result.expires = 18000
71
72
72 celeryd.concurrency = 2
73 celeryd.concurrency = 2
73 #celeryd.log.file = celeryd.log
74 #celeryd.log.file = celeryd.log
74 celeryd.log.level = debug
75 celeryd.log.level = debug
75 celeryd.max.tasks.per.child = 1
76 celeryd.max.tasks.per.child = 1
76
77
77 #tasks will never be sent to the queue, but executed locally instead.
78 #tasks will never be sent to the queue, but executed locally instead.
78 celery.always.eager = false
79 celery.always.eager = false
79
80
80 ####################################
81 ####################################
81 ### BEAKER CACHE ####
82 ### BEAKER CACHE ####
82 ####################################
83 ####################################
83 beaker.cache.data_dir=%(here)s/data/cache/data
84 beaker.cache.data_dir=%(here)s/data/cache/data
84 beaker.cache.lock_dir=%(here)s/data/cache/lock
85 beaker.cache.lock_dir=%(here)s/data/cache/lock
85
86
86 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
87 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
87
88
88 beaker.cache.super_short_term.type=memory
89 beaker.cache.super_short_term.type=memory
89 beaker.cache.super_short_term.expire=10
90 beaker.cache.super_short_term.expire=10
90
91
91 beaker.cache.short_term.type=memory
92 beaker.cache.short_term.type=memory
92 beaker.cache.short_term.expire=60
93 beaker.cache.short_term.expire=60
93
94
94 beaker.cache.long_term.type=memory
95 beaker.cache.long_term.type=memory
95 beaker.cache.long_term.expire=36000
96 beaker.cache.long_term.expire=36000
96
97
97 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.type=memory
98 beaker.cache.sql_cache_short.expire=10
99 beaker.cache.sql_cache_short.expire=10
99
100
100 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.type=memory
101 beaker.cache.sql_cache_med.expire=360
102 beaker.cache.sql_cache_med.expire=360
102
103
103 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.type=file
104 beaker.cache.sql_cache_long.expire=3600
105 beaker.cache.sql_cache_long.expire=3600
105
106
106 ####################################
107 ####################################
107 ### BEAKER SESSION ####
108 ### BEAKER SESSION ####
108 ####################################
109 ####################################
109 ## Type of storage used for the session, current types are
110 ## Type of storage used for the session, current types are
110 ## dbm, file, memcached, database, and memory.
111 ## dbm, file, memcached, database, and memory.
111 ## The storage uses the Container API
112 ## The storage uses the Container API
112 ##that is also used by the cache system.
113 ##that is also used by the cache system.
113 beaker.session.type = file
114 beaker.session.type = file
114
115
115 beaker.session.key = rhodecode
116 beaker.session.key = rhodecode
116 beaker.session.secret = ${app_instance_secret}
117 beaker.session.secret = ${app_instance_secret}
117 beaker.session.timeout = 36000
118 beaker.session.timeout = 36000
118
119
119 ##auto save the session to not to use .save()
120 ##auto save the session to not to use .save()
120 beaker.session.auto = False
121 beaker.session.auto = False
121
122
122 ##true exire at browser close
123 ##true exire at browser close
123 #beaker.session.cookie_expires = 3600
124 #beaker.session.cookie_expires = 3600
124
125
125
126
126 ################################################################################
127 ################################################################################
127 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
128 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
129 ## execute malicious code after an exception is raised. ##
130 ## execute malicious code after an exception is raised. ##
130 ################################################################################
131 ################################################################################
131 set debug = false
132 set debug = false
132
133
133 ##################################
134 ##################################
134 ### LOGVIEW CONFIG ###
135 ### LOGVIEW CONFIG ###
135 ##################################
136 ##################################
136 logview.sqlalchemy = #faa
137 logview.sqlalchemy = #faa
137 logview.pylons.templating = #bfb
138 logview.pylons.templating = #bfb
138 logview.pylons.util = #eee
139 logview.pylons.util = #eee
139
140
140 #########################################################
141 #########################################################
141 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
142 #########################################################
143 #########################################################
143 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
144 #sqlalchemy.db1.echo = False
145 #sqlalchemy.db1.echo = False
145 #sqlalchemy.db1.pool_recycle = 3600
146 #sqlalchemy.db1.pool_recycle = 3600
146 sqlalchemy.convert_unicode = true
147 sqlalchemy.convert_unicode = true
147
148
148 ################################
149 ################################
149 ### LOGGING CONFIGURATION ####
150 ### LOGGING CONFIGURATION ####
150 ################################
151 ################################
151 [loggers]
152 [loggers]
152 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
153 keys = root, routes, rhodecode, sqlalchemy,beaker,templates
153
154
154 [handlers]
155 [handlers]
155 keys = console
156 keys = console
156
157
157 [formatters]
158 [formatters]
158 keys = generic,color_formatter
159 keys = generic,color_formatter
159
160
160 #############
161 #############
161 ## LOGGERS ##
162 ## LOGGERS ##
162 #############
163 #############
163 [logger_root]
164 [logger_root]
164 level = INFO
165 level = INFO
165 handlers = console
166 handlers = console
166
167
167 [logger_routes]
168 [logger_routes]
168 level = INFO
169 level = INFO
169 handlers = console
170 handlers = console
170 qualname = routes.middleware
171 qualname = routes.middleware
171 # "level = DEBUG" logs the route matched and routing variables.
172 # "level = DEBUG" logs the route matched and routing variables.
172 propagate = 0
173 propagate = 0
173
174
174 [logger_beaker]
175 [logger_beaker]
175 level = ERROR
176 level = ERROR
176 handlers = console
177 handlers = console
177 qualname = beaker.container
178 qualname = beaker.container
178 propagate = 0
179 propagate = 0
179
180
180 [logger_templates]
181 [logger_templates]
181 level = INFO
182 level = INFO
182 handlers = console
183 handlers = console
183 qualname = pylons.templating
184 qualname = pylons.templating
184 propagate = 0
185 propagate = 0
185
186
186 [logger_rhodecode]
187 [logger_rhodecode]
187 level = DEBUG
188 level = DEBUG
188 handlers = console
189 handlers = console
189 qualname = rhodecode
190 qualname = rhodecode
190 propagate = 0
191 propagate = 0
191
192
192 [logger_sqlalchemy]
193 [logger_sqlalchemy]
193 level = ERROR
194 level = ERROR
194 handlers = console
195 handlers = console
195 qualname = sqlalchemy.engine
196 qualname = sqlalchemy.engine
196 propagate = 0
197 propagate = 0
197
198
198 ##############
199 ##############
199 ## HANDLERS ##
200 ## HANDLERS ##
200 ##############
201 ##############
201
202
202 [handler_console]
203 [handler_console]
203 class = StreamHandler
204 class = StreamHandler
204 args = (sys.stderr,)
205 args = (sys.stderr,)
205 level = NOTSET
206 level = NOTSET
206 formatter = color_formatter
207 formatter = color_formatter
207
208
208 ################
209 ################
209 ## FORMATTERS ##
210 ## FORMATTERS ##
210 ################
211 ################
211
212
212 [formatter_generic]
213 [formatter_generic]
213 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
214 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
214 datefmt = %Y-%m-%d %H:%M:%S
215 datefmt = %Y-%m-%d %H:%M:%S
215
216
216 [formatter_color_formatter]
217 [formatter_color_formatter]
217 class=rhodecode.lib.colored_formatter.ColorFormatter
218 class=rhodecode.lib.colored_formatter.ColorFormatter
218 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
219 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
219 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
220 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,694 +1,698 b''
1 """Helper functions
1 """Helper functions
2
2
3 Consists of functions to typically be used within templates, but also
3 Consists of functions to typically be used within templates, but also
4 available to Controllers. This module is available to both as 'h'.
4 available to Controllers. This module is available to both as 'h'.
5 """
5 """
6 import random
6 import random
7 import hashlib
7 import hashlib
8 import StringIO
8 import StringIO
9 import urllib
9 import urllib
10
10
11 from pygments.formatters import HtmlFormatter
11 from pygments.formatters import HtmlFormatter
12 from pygments import highlight as code_highlight
12 from pygments import highlight as code_highlight
13 from pylons import url, request
13 from pylons import url, request, config
14 from pylons.i18n.translation import _, ungettext
14 from pylons.i18n.translation import _, ungettext
15
15
16 from webhelpers.html import literal, HTML, escape
16 from webhelpers.html import literal, HTML, escape
17 from webhelpers.html.tools import *
17 from webhelpers.html.tools import *
18 from webhelpers.html.builder import make_tag
18 from webhelpers.html.builder import make_tag
19 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
19 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
20 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
20 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
21 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
21 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
22 password, textarea, title, ul, xml_declaration, radio
22 password, textarea, title, ul, xml_declaration, radio
23 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
23 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
24 mail_to, strip_links, strip_tags, tag_re
24 mail_to, strip_links, strip_tags, tag_re
25 from webhelpers.number import format_byte_size, format_bit_size
25 from webhelpers.number import format_byte_size, format_bit_size
26 from webhelpers.pylonslib import Flash as _Flash
26 from webhelpers.pylonslib import Flash as _Flash
27 from webhelpers.pylonslib.secure_form import secure_form
27 from webhelpers.pylonslib.secure_form import secure_form
28 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
28 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
29 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
29 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
30 replace_whitespace, urlify, truncate, wrap_paragraphs
30 replace_whitespace, urlify, truncate, wrap_paragraphs
31 from webhelpers.date import time_ago_in_words
31 from webhelpers.date import time_ago_in_words
32 from webhelpers.paginate import Page
32 from webhelpers.paginate import Page
33 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
33 from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \
34 convert_boolean_attrs, NotGiven
34 convert_boolean_attrs, NotGiven
35
35
36 from vcs.utils.annotate import annotate_highlight
36 from vcs.utils.annotate import annotate_highlight
37 from rhodecode.lib.utils import repo_name_slug
37 from rhodecode.lib.utils import repo_name_slug
38 from rhodecode.lib import str2bool
38
39
39 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
40 def _reset(name, value=None, id=NotGiven, type="reset", **attrs):
40 """Reset button
41 """Reset button
41 """
42 """
42 _set_input_attrs(attrs, type, name, value)
43 _set_input_attrs(attrs, type, name, value)
43 _set_id_attr(attrs, id, name)
44 _set_id_attr(attrs, id, name)
44 convert_boolean_attrs(attrs, ["disabled"])
45 convert_boolean_attrs(attrs, ["disabled"])
45 return HTML.input(**attrs)
46 return HTML.input(**attrs)
46
47
47 reset = _reset
48 reset = _reset
48
49
49
50
50 def get_token():
51 def get_token():
51 """Return the current authentication token, creating one if one doesn't
52 """Return the current authentication token, creating one if one doesn't
52 already exist.
53 already exist.
53 """
54 """
54 token_key = "_authentication_token"
55 token_key = "_authentication_token"
55 from pylons import session
56 from pylons import session
56 if not token_key in session:
57 if not token_key in session:
57 try:
58 try:
58 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
59 token = hashlib.sha1(str(random.getrandbits(128))).hexdigest()
59 except AttributeError: # Python < 2.4
60 except AttributeError: # Python < 2.4
60 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
61 token = hashlib.sha1(str(random.randrange(2 ** 128))).hexdigest()
61 session[token_key] = token
62 session[token_key] = token
62 if hasattr(session, 'save'):
63 if hasattr(session, 'save'):
63 session.save()
64 session.save()
64 return session[token_key]
65 return session[token_key]
65
66
66 class _GetError(object):
67 class _GetError(object):
67 """Get error from form_errors, and represent it as span wrapped error
68 """Get error from form_errors, and represent it as span wrapped error
68 message
69 message
69
70
70 :param field_name: field to fetch errors for
71 :param field_name: field to fetch errors for
71 :param form_errors: form errors dict
72 :param form_errors: form errors dict
72 """
73 """
73
74
74 def __call__(self, field_name, form_errors):
75 def __call__(self, field_name, form_errors):
75 tmpl = """<span class="error_msg">%s</span>"""
76 tmpl = """<span class="error_msg">%s</span>"""
76 if form_errors and form_errors.has_key(field_name):
77 if form_errors and form_errors.has_key(field_name):
77 return literal(tmpl % form_errors.get(field_name))
78 return literal(tmpl % form_errors.get(field_name))
78
79
79 get_error = _GetError()
80 get_error = _GetError()
80
81
81 class _ToolTip(object):
82 class _ToolTip(object):
82
83
83 def __call__(self, tooltip_title, trim_at=50):
84 def __call__(self, tooltip_title, trim_at=50):
84 """Special function just to wrap our text into nice formatted
85 """Special function just to wrap our text into nice formatted
85 autowrapped text
86 autowrapped text
86
87
87 :param tooltip_title:
88 :param tooltip_title:
88 """
89 """
89
90
90 return wrap_paragraphs(escape(tooltip_title), trim_at)\
91 return wrap_paragraphs(escape(tooltip_title), trim_at)\
91 .replace('\n', '<br/>')
92 .replace('\n', '<br/>')
92
93
93 def activate(self):
94 def activate(self):
94 """Adds tooltip mechanism to the given Html all tooltips have to have
95 """Adds tooltip mechanism to the given Html all tooltips have to have
95 set class `tooltip` and set attribute `tooltip_title`.
96 set class `tooltip` and set attribute `tooltip_title`.
96 Then a tooltip will be generated based on that. All with yui js tooltip
97 Then a tooltip will be generated based on that. All with yui js tooltip
97 """
98 """
98
99
99 js = '''
100 js = '''
100 YAHOO.util.Event.onDOMReady(function(){
101 YAHOO.util.Event.onDOMReady(function(){
101 function toolTipsId(){
102 function toolTipsId(){
102 var ids = [];
103 var ids = [];
103 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
104 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
104
105
105 for (var i = 0; i < tts.length; i++) {
106 for (var i = 0; i < tts.length; i++) {
106 //if element doesn't not have and id autogenerate one for tooltip
107 //if element doesn't not have and id autogenerate one for tooltip
107
108
108 if (!tts[i].id){
109 if (!tts[i].id){
109 tts[i].id='tt'+i*100;
110 tts[i].id='tt'+i*100;
110 }
111 }
111 ids.push(tts[i].id);
112 ids.push(tts[i].id);
112 }
113 }
113 return ids
114 return ids
114 };
115 };
115 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
116 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
116 context: toolTipsId(),
117 context: toolTipsId(),
117 monitorresize:false,
118 monitorresize:false,
118 xyoffset :[0,0],
119 xyoffset :[0,0],
119 autodismissdelay:300000,
120 autodismissdelay:300000,
120 hidedelay:5,
121 hidedelay:5,
121 showdelay:20,
122 showdelay:20,
122 });
123 });
123
124
124 // Set the text for the tooltip just before we display it. Lazy method
125 // Set the text for the tooltip just before we display it. Lazy method
125 myToolTips.contextTriggerEvent.subscribe(
126 myToolTips.contextTriggerEvent.subscribe(
126 function(type, args) {
127 function(type, args) {
127
128
128 var context = args[0];
129 var context = args[0];
129
130
130 //positioning of tooltip
131 //positioning of tooltip
131 var tt_w = this.element.clientWidth;//tooltip width
132 var tt_w = this.element.clientWidth;//tooltip width
132 var tt_h = this.element.clientHeight;//tooltip height
133 var tt_h = this.element.clientHeight;//tooltip height
133
134
134 var context_w = context.offsetWidth;
135 var context_w = context.offsetWidth;
135 var context_h = context.offsetHeight;
136 var context_h = context.offsetHeight;
136
137
137 var pos_x = YAHOO.util.Dom.getX(context);
138 var pos_x = YAHOO.util.Dom.getX(context);
138 var pos_y = YAHOO.util.Dom.getY(context);
139 var pos_y = YAHOO.util.Dom.getY(context);
139
140
140 var display_strategy = 'right';
141 var display_strategy = 'right';
141 var xy_pos = [0,0];
142 var xy_pos = [0,0];
142 switch (display_strategy){
143 switch (display_strategy){
143
144
144 case 'top':
145 case 'top':
145 var cur_x = (pos_x+context_w/2)-(tt_w/2);
146 var cur_x = (pos_x+context_w/2)-(tt_w/2);
146 var cur_y = (pos_y-tt_h-4);
147 var cur_y = (pos_y-tt_h-4);
147 xy_pos = [cur_x,cur_y];
148 xy_pos = [cur_x,cur_y];
148 break;
149 break;
149 case 'bottom':
150 case 'bottom':
150 var cur_x = (pos_x+context_w/2)-(tt_w/2);
151 var cur_x = (pos_x+context_w/2)-(tt_w/2);
151 var cur_y = pos_y+context_h+4;
152 var cur_y = pos_y+context_h+4;
152 xy_pos = [cur_x,cur_y];
153 xy_pos = [cur_x,cur_y];
153 break;
154 break;
154 case 'left':
155 case 'left':
155 var cur_x = (pos_x-tt_w-4);
156 var cur_x = (pos_x-tt_w-4);
156 var cur_y = pos_y-((tt_h/2)-context_h/2);
157 var cur_y = pos_y-((tt_h/2)-context_h/2);
157 xy_pos = [cur_x,cur_y];
158 xy_pos = [cur_x,cur_y];
158 break;
159 break;
159 case 'right':
160 case 'right':
160 var cur_x = (pos_x+context_w+4);
161 var cur_x = (pos_x+context_w+4);
161 var cur_y = pos_y-((tt_h/2)-context_h/2);
162 var cur_y = pos_y-((tt_h/2)-context_h/2);
162 xy_pos = [cur_x,cur_y];
163 xy_pos = [cur_x,cur_y];
163 break;
164 break;
164 default:
165 default:
165 var cur_x = (pos_x+context_w/2)-(tt_w/2);
166 var cur_x = (pos_x+context_w/2)-(tt_w/2);
166 var cur_y = pos_y-tt_h-4;
167 var cur_y = pos_y-tt_h-4;
167 xy_pos = [cur_x,cur_y];
168 xy_pos = [cur_x,cur_y];
168 break;
169 break;
169
170
170 }
171 }
171
172
172 this.cfg.setProperty("xy",xy_pos);
173 this.cfg.setProperty("xy",xy_pos);
173
174
174 });
175 });
175
176
176 //Mouse out
177 //Mouse out
177 myToolTips.contextMouseOutEvent.subscribe(
178 myToolTips.contextMouseOutEvent.subscribe(
178 function(type, args) {
179 function(type, args) {
179 var context = args[0];
180 var context = args[0];
180
181
181 });
182 });
182 });
183 });
183 '''
184 '''
184 return literal(js)
185 return literal(js)
185
186
186 tooltip = _ToolTip()
187 tooltip = _ToolTip()
187
188
188 class _FilesBreadCrumbs(object):
189 class _FilesBreadCrumbs(object):
189
190
190 def __call__(self, repo_name, rev, paths):
191 def __call__(self, repo_name, rev, paths):
191 if isinstance(paths, str):
192 if isinstance(paths, str):
192 paths = paths.decode('utf-8', 'replace')
193 paths = paths.decode('utf-8', 'replace')
193 url_l = [link_to(repo_name, url('files_home',
194 url_l = [link_to(repo_name, url('files_home',
194 repo_name=repo_name,
195 repo_name=repo_name,
195 revision=rev, f_path=''))]
196 revision=rev, f_path=''))]
196 paths_l = paths.split('/')
197 paths_l = paths.split('/')
197 for cnt, p in enumerate(paths_l):
198 for cnt, p in enumerate(paths_l):
198 if p != '':
199 if p != '':
199 url_l.append(link_to(p, url('files_home',
200 url_l.append(link_to(p, url('files_home',
200 repo_name=repo_name,
201 repo_name=repo_name,
201 revision=rev,
202 revision=rev,
202 f_path='/'.join(paths_l[:cnt + 1]))))
203 f_path='/'.join(paths_l[:cnt + 1]))))
203
204
204 return literal('/'.join(url_l))
205 return literal('/'.join(url_l))
205
206
206 files_breadcrumbs = _FilesBreadCrumbs()
207 files_breadcrumbs = _FilesBreadCrumbs()
207
208
208 class CodeHtmlFormatter(HtmlFormatter):
209 class CodeHtmlFormatter(HtmlFormatter):
209 """My code Html Formatter for source codes
210 """My code Html Formatter for source codes
210 """
211 """
211
212
212 def wrap(self, source, outfile):
213 def wrap(self, source, outfile):
213 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
214 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
214
215
215 def _wrap_code(self, source):
216 def _wrap_code(self, source):
216 for cnt, it in enumerate(source):
217 for cnt, it in enumerate(source):
217 i, t = it
218 i, t = it
218 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
219 t = '<div id="L%s">%s</div>' % (cnt + 1, t)
219 yield i, t
220 yield i, t
220
221
221 def _wrap_tablelinenos(self, inner):
222 def _wrap_tablelinenos(self, inner):
222 dummyoutfile = StringIO.StringIO()
223 dummyoutfile = StringIO.StringIO()
223 lncount = 0
224 lncount = 0
224 for t, line in inner:
225 for t, line in inner:
225 if t:
226 if t:
226 lncount += 1
227 lncount += 1
227 dummyoutfile.write(line)
228 dummyoutfile.write(line)
228
229
229 fl = self.linenostart
230 fl = self.linenostart
230 mw = len(str(lncount + fl - 1))
231 mw = len(str(lncount + fl - 1))
231 sp = self.linenospecial
232 sp = self.linenospecial
232 st = self.linenostep
233 st = self.linenostep
233 la = self.lineanchors
234 la = self.lineanchors
234 aln = self.anchorlinenos
235 aln = self.anchorlinenos
235 nocls = self.noclasses
236 nocls = self.noclasses
236 if sp:
237 if sp:
237 lines = []
238 lines = []
238
239
239 for i in range(fl, fl + lncount):
240 for i in range(fl, fl + lncount):
240 if i % st == 0:
241 if i % st == 0:
241 if i % sp == 0:
242 if i % sp == 0:
242 if aln:
243 if aln:
243 lines.append('<a href="#%s%d" class="special">%*d</a>' %
244 lines.append('<a href="#%s%d" class="special">%*d</a>' %
244 (la, i, mw, i))
245 (la, i, mw, i))
245 else:
246 else:
246 lines.append('<span class="special">%*d</span>' % (mw, i))
247 lines.append('<span class="special">%*d</span>' % (mw, i))
247 else:
248 else:
248 if aln:
249 if aln:
249 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
250 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
250 else:
251 else:
251 lines.append('%*d' % (mw, i))
252 lines.append('%*d' % (mw, i))
252 else:
253 else:
253 lines.append('')
254 lines.append('')
254 ls = '\n'.join(lines)
255 ls = '\n'.join(lines)
255 else:
256 else:
256 lines = []
257 lines = []
257 for i in range(fl, fl + lncount):
258 for i in range(fl, fl + lncount):
258 if i % st == 0:
259 if i % st == 0:
259 if aln:
260 if aln:
260 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
261 lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i))
261 else:
262 else:
262 lines.append('%*d' % (mw, i))
263 lines.append('%*d' % (mw, i))
263 else:
264 else:
264 lines.append('')
265 lines.append('')
265 ls = '\n'.join(lines)
266 ls = '\n'.join(lines)
266
267
267 # in case you wonder about the seemingly redundant <div> here: since the
268 # in case you wonder about the seemingly redundant <div> here: since the
268 # content in the other cell also is wrapped in a div, some browsers in
269 # content in the other cell also is wrapped in a div, some browsers in
269 # some configurations seem to mess up the formatting...
270 # some configurations seem to mess up the formatting...
270 if nocls:
271 if nocls:
271 yield 0, ('<table class="%stable">' % self.cssclass +
272 yield 0, ('<table class="%stable">' % self.cssclass +
272 '<tr><td><div class="linenodiv" '
273 '<tr><td><div class="linenodiv" '
273 'style="background-color: #f0f0f0; padding-right: 10px">'
274 'style="background-color: #f0f0f0; padding-right: 10px">'
274 '<pre style="line-height: 125%">' +
275 '<pre style="line-height: 125%">' +
275 ls + '</pre></div></td><td class="code">')
276 ls + '</pre></div></td><td class="code">')
276 else:
277 else:
277 yield 0, ('<table class="%stable">' % self.cssclass +
278 yield 0, ('<table class="%stable">' % self.cssclass +
278 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
279 '<tr><td class="linenos"><div class="linenodiv"><pre>' +
279 ls + '</pre></div></td><td class="code">')
280 ls + '</pre></div></td><td class="code">')
280 yield 0, dummyoutfile.getvalue()
281 yield 0, dummyoutfile.getvalue()
281 yield 0, '</td></tr></table>'
282 yield 0, '</td></tr></table>'
282
283
283
284
284 def pygmentize(filenode, **kwargs):
285 def pygmentize(filenode, **kwargs):
285 """pygmentize function using pygments
286 """pygmentize function using pygments
286
287
287 :param filenode:
288 :param filenode:
288 """
289 """
289
290
290 return literal(code_highlight(filenode.content,
291 return literal(code_highlight(filenode.content,
291 filenode.lexer, CodeHtmlFormatter(**kwargs)))
292 filenode.lexer, CodeHtmlFormatter(**kwargs)))
292
293
293 def pygmentize_annotation(filenode, **kwargs):
294 def pygmentize_annotation(filenode, **kwargs):
294 """pygmentize function for annotation
295 """pygmentize function for annotation
295
296
296 :param filenode:
297 :param filenode:
297 """
298 """
298
299
299 color_dict = {}
300 color_dict = {}
300 def gen_color(n=10000):
301 def gen_color(n=10000):
301 """generator for getting n of evenly distributed colors using
302 """generator for getting n of evenly distributed colors using
302 hsv color and golden ratio. It always return same order of colors
303 hsv color and golden ratio. It always return same order of colors
303
304
304 :returns: RGB tuple
305 :returns: RGB tuple
305 """
306 """
306 import colorsys
307 import colorsys
307 golden_ratio = 0.618033988749895
308 golden_ratio = 0.618033988749895
308 h = 0.22717784590367374
309 h = 0.22717784590367374
309
310
310 for c in xrange(n):
311 for c in xrange(n):
311 h += golden_ratio
312 h += golden_ratio
312 h %= 1
313 h %= 1
313 HSV_tuple = [h, 0.95, 0.95]
314 HSV_tuple = [h, 0.95, 0.95]
314 RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
315 RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
315 yield map(lambda x:str(int(x * 256)), RGB_tuple)
316 yield map(lambda x:str(int(x * 256)), RGB_tuple)
316
317
317 cgenerator = gen_color()
318 cgenerator = gen_color()
318
319
319 def get_color_string(cs):
320 def get_color_string(cs):
320 if color_dict.has_key(cs):
321 if color_dict.has_key(cs):
321 col = color_dict[cs]
322 col = color_dict[cs]
322 else:
323 else:
323 col = color_dict[cs] = cgenerator.next()
324 col = color_dict[cs] = cgenerator.next()
324 return "color: rgb(%s)! important;" % (', '.join(col))
325 return "color: rgb(%s)! important;" % (', '.join(col))
325
326
326 def url_func(changeset):
327 def url_func(changeset):
327 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
328 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
328 " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
329 " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
329
330
330 tooltip_html = tooltip_html % (changeset.author,
331 tooltip_html = tooltip_html % (changeset.author,
331 changeset.date,
332 changeset.date,
332 tooltip(changeset.message))
333 tooltip(changeset.message))
333 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
334 lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
334 short_id(changeset.raw_id))
335 short_id(changeset.raw_id))
335 uri = link_to(
336 uri = link_to(
336 lnk_format,
337 lnk_format,
337 url('changeset_home', repo_name=changeset.repository.name,
338 url('changeset_home', repo_name=changeset.repository.name,
338 revision=changeset.raw_id),
339 revision=changeset.raw_id),
339 style=get_color_string(changeset.raw_id),
340 style=get_color_string(changeset.raw_id),
340 class_='tooltip',
341 class_='tooltip',
341 title=tooltip_html
342 title=tooltip_html
342 )
343 )
343
344
344 uri += '\n'
345 uri += '\n'
345 return uri
346 return uri
346 return literal(annotate_highlight(filenode, url_func, **kwargs))
347 return literal(annotate_highlight(filenode, url_func, **kwargs))
347
348
348 def get_changeset_safe(repo, rev):
349 def get_changeset_safe(repo, rev):
349 from vcs.backends.base import BaseRepository
350 from vcs.backends.base import BaseRepository
350 from vcs.exceptions import RepositoryError
351 from vcs.exceptions import RepositoryError
351 if not isinstance(repo, BaseRepository):
352 if not isinstance(repo, BaseRepository):
352 raise Exception('You must pass an Repository '
353 raise Exception('You must pass an Repository '
353 'object as first argument got %s', type(repo))
354 'object as first argument got %s', type(repo))
354
355
355 try:
356 try:
356 cs = repo.get_changeset(rev)
357 cs = repo.get_changeset(rev)
357 except RepositoryError:
358 except RepositoryError:
358 from rhodecode.lib.utils import EmptyChangeset
359 from rhodecode.lib.utils import EmptyChangeset
359 cs = EmptyChangeset()
360 cs = EmptyChangeset()
360 return cs
361 return cs
361
362
362
363
363 def is_following_repo(repo_name, user_id):
364 def is_following_repo(repo_name, user_id):
364 from rhodecode.model.scm import ScmModel
365 from rhodecode.model.scm import ScmModel
365 return ScmModel().is_following_repo(repo_name, user_id)
366 return ScmModel().is_following_repo(repo_name, user_id)
366
367
367 flash = _Flash()
368 flash = _Flash()
368
369
369
370
370 #==============================================================================
371 #==============================================================================
371 # MERCURIAL FILTERS available via h.
372 # MERCURIAL FILTERS available via h.
372 #==============================================================================
373 #==============================================================================
373 from mercurial import util
374 from mercurial import util
374 from mercurial.templatefilters import person as _person
375 from mercurial.templatefilters import person as _person
375
376
376 def _age(curdate):
377 def _age(curdate):
377 """turns a datetime into an age string."""
378 """turns a datetime into an age string."""
378
379
379 if not curdate:
380 if not curdate:
380 return ''
381 return ''
381
382
382 from datetime import timedelta, datetime
383 from datetime import timedelta, datetime
383
384
384 agescales = [("year", 3600 * 24 * 365),
385 agescales = [("year", 3600 * 24 * 365),
385 ("month", 3600 * 24 * 30),
386 ("month", 3600 * 24 * 30),
386 ("day", 3600 * 24),
387 ("day", 3600 * 24),
387 ("hour", 3600),
388 ("hour", 3600),
388 ("minute", 60),
389 ("minute", 60),
389 ("second", 1), ]
390 ("second", 1), ]
390
391
391 age = datetime.now() - curdate
392 age = datetime.now() - curdate
392 age_seconds = (age.days * agescales[2][1]) + age.seconds
393 age_seconds = (age.days * agescales[2][1]) + age.seconds
393 pos = 1
394 pos = 1
394 for scale in agescales:
395 for scale in agescales:
395 if scale[1] <= age_seconds:
396 if scale[1] <= age_seconds:
396 if pos == 6:pos = 5
397 if pos == 6:pos = 5
397 return time_ago_in_words(curdate, agescales[pos][0]) + ' ' + _('ago')
398 return time_ago_in_words(curdate, agescales[pos][0]) + ' ' + _('ago')
398 pos += 1
399 pos += 1
399
400
400 return _('just now')
401 return _('just now')
401
402
402 age = lambda x:_age(x)
403 age = lambda x:_age(x)
403 capitalize = lambda x: x.capitalize()
404 capitalize = lambda x: x.capitalize()
404 email = util.email
405 email = util.email
405 email_or_none = lambda x: util.email(x) if util.email(x) != x else None
406 email_or_none = lambda x: util.email(x) if util.email(x) != x else None
406 person = lambda x: _person(x)
407 person = lambda x: _person(x)
407 short_id = lambda x: x[:12]
408 short_id = lambda x: x[:12]
408
409
409
410
410 def bool2icon(value):
411 def bool2icon(value):
411 """Returns True/False values represented as small html image of true/false
412 """Returns True/False values represented as small html image of true/false
412 icons
413 icons
413
414
414 :param value: bool value
415 :param value: bool value
415 """
416 """
416
417
417 if value is True:
418 if value is True:
418 return HTML.tag('img', src=url("/images/icons/accept.png"),
419 return HTML.tag('img', src=url("/images/icons/accept.png"),
419 alt=_('True'))
420 alt=_('True'))
420
421
421 if value is False:
422 if value is False:
422 return HTML.tag('img', src=url("/images/icons/cancel.png"),
423 return HTML.tag('img', src=url("/images/icons/cancel.png"),
423 alt=_('False'))
424 alt=_('False'))
424
425
425 return value
426 return value
426
427
427
428
428 def action_parser(user_log, feed=False):
429 def action_parser(user_log, feed=False):
429 """This helper will action_map the specified string action into translated
430 """This helper will action_map the specified string action into translated
430 fancy names with icons and links
431 fancy names with icons and links
431
432
432 :param user_log: user log instance
433 :param user_log: user log instance
433 :param feed: use output for feeds (no html and fancy icons)
434 :param feed: use output for feeds (no html and fancy icons)
434 """
435 """
435
436
436 action = user_log.action
437 action = user_log.action
437 action_params = ' '
438 action_params = ' '
438
439
439 x = action.split(':')
440 x = action.split(':')
440
441
441 if len(x) > 1:
442 if len(x) > 1:
442 action, action_params = x
443 action, action_params = x
443
444
444 def get_cs_links():
445 def get_cs_links():
445 revs_limit = 5 #display this amount always
446 revs_limit = 5 #display this amount always
446 revs_top_limit = 50 #show upto this amount of changesets hidden
447 revs_top_limit = 50 #show upto this amount of changesets hidden
447 revs = action_params.split(',')
448 revs = action_params.split(',')
448 repo_name = user_log.repository.repo_name
449 repo_name = user_log.repository.repo_name
449
450
450 from rhodecode.model.scm import ScmModel
451 from rhodecode.model.scm import ScmModel
451 repo, dbrepo = ScmModel().get(repo_name, retval='repo',
452 repo, dbrepo = ScmModel().get(repo_name, retval='repo',
452 invalidation_list=[])
453 invalidation_list=[])
453
454
454 message = lambda rev: get_changeset_safe(repo, rev).message
455 message = lambda rev: get_changeset_safe(repo, rev).message
455
456
456 cs_links = " " + ', '.join ([link_to(rev,
457 cs_links = " " + ', '.join ([link_to(rev,
457 url('changeset_home',
458 url('changeset_home',
458 repo_name=repo_name,
459 repo_name=repo_name,
459 revision=rev), title=tooltip(message(rev)),
460 revision=rev), title=tooltip(message(rev)),
460 class_='tooltip') for rev in revs[:revs_limit] ])
461 class_='tooltip') for rev in revs[:revs_limit] ])
461
462
462 compare_view = (' <div class="compare_view tooltip" title="%s">'
463 compare_view = (' <div class="compare_view tooltip" title="%s">'
463 '<a href="%s">%s</a> '
464 '<a href="%s">%s</a> '
464 '</div>' % (_('Show all combined changesets %s->%s' \
465 '</div>' % (_('Show all combined changesets %s->%s' \
465 % (revs[0], revs[-1])),
466 % (revs[0], revs[-1])),
466 url('changeset_home', repo_name=repo_name,
467 url('changeset_home', repo_name=repo_name,
467 revision='%s...%s' % (revs[0], revs[-1])
468 revision='%s...%s' % (revs[0], revs[-1])
468 ),
469 ),
469 _('compare view'))
470 _('compare view'))
470 )
471 )
471
472
472 if len(revs) > revs_limit:
473 if len(revs) > revs_limit:
473 uniq_id = revs[0]
474 uniq_id = revs[0]
474 html_tmpl = ('<span> %s '
475 html_tmpl = ('<span> %s '
475 '<a class="show_more" id="_%s" href="#more">%s</a> '
476 '<a class="show_more" id="_%s" href="#more">%s</a> '
476 '%s</span>')
477 '%s</span>')
477 if not feed:
478 if not feed:
478 cs_links += html_tmpl % (_('and'), uniq_id, _('%s more') \
479 cs_links += html_tmpl % (_('and'), uniq_id, _('%s more') \
479 % (len(revs) - revs_limit),
480 % (len(revs) - revs_limit),
480 _('revisions'))
481 _('revisions'))
481
482
482 if not feed:
483 if not feed:
483 html_tmpl = '<span id="%s" style="display:none"> %s </span>'
484 html_tmpl = '<span id="%s" style="display:none"> %s </span>'
484 else:
485 else:
485 html_tmpl = '<span id="%s"> %s </span>'
486 html_tmpl = '<span id="%s"> %s </span>'
486
487
487 cs_links += html_tmpl % (uniq_id, ', '.join([link_to(rev,
488 cs_links += html_tmpl % (uniq_id, ', '.join([link_to(rev,
488 url('changeset_home',
489 url('changeset_home',
489 repo_name=repo_name, revision=rev),
490 repo_name=repo_name, revision=rev),
490 title=message(rev), class_='tooltip')
491 title=message(rev), class_='tooltip')
491 for rev in revs[revs_limit:revs_top_limit]]))
492 for rev in revs[revs_limit:revs_top_limit]]))
492 if len(revs) > 1:
493 if len(revs) > 1:
493 cs_links += compare_view
494 cs_links += compare_view
494 return cs_links
495 return cs_links
495
496
496 def get_fork_name():
497 def get_fork_name():
497 repo_name = action_params
498 repo_name = action_params
498 return _('fork name ') + str(link_to(action_params, url('summary_home',
499 return _('fork name ') + str(link_to(action_params, url('summary_home',
499 repo_name=repo_name,)))
500 repo_name=repo_name,)))
500
501
501 action_map = {'user_deleted_repo':(_('[deleted] repository'), None),
502 action_map = {'user_deleted_repo':(_('[deleted] repository'), None),
502 'user_created_repo':(_('[created] repository'), None),
503 'user_created_repo':(_('[created] repository'), None),
503 'user_forked_repo':(_('[forked] repository'), get_fork_name),
504 'user_forked_repo':(_('[forked] repository'), get_fork_name),
504 'user_updated_repo':(_('[updated] repository'), None),
505 'user_updated_repo':(_('[updated] repository'), None),
505 'admin_deleted_repo':(_('[delete] repository'), None),
506 'admin_deleted_repo':(_('[delete] repository'), None),
506 'admin_created_repo':(_('[created] repository'), None),
507 'admin_created_repo':(_('[created] repository'), None),
507 'admin_forked_repo':(_('[forked] repository'), None),
508 'admin_forked_repo':(_('[forked] repository'), None),
508 'admin_updated_repo':(_('[updated] repository'), None),
509 'admin_updated_repo':(_('[updated] repository'), None),
509 'push':(_('[pushed] into'), get_cs_links),
510 'push':(_('[pushed] into'), get_cs_links),
510 'push_remote':(_('[pulled from remote] into'), get_cs_links),
511 'push_remote':(_('[pulled from remote] into'), get_cs_links),
511 'pull':(_('[pulled] from'), None),
512 'pull':(_('[pulled] from'), None),
512 'started_following_repo':(_('[started following] repository'), None),
513 'started_following_repo':(_('[started following] repository'), None),
513 'stopped_following_repo':(_('[stopped following] repository'), None),
514 'stopped_following_repo':(_('[stopped following] repository'), None),
514 }
515 }
515
516
516 action_str = action_map.get(action, action)
517 action_str = action_map.get(action, action)
517 if feed:
518 if feed:
518 action = action_str[0].replace('[', '').replace(']', '')
519 action = action_str[0].replace('[', '').replace(']', '')
519 else:
520 else:
520 action = action_str[0].replace('[', '<span class="journal_highlight">')\
521 action = action_str[0].replace('[', '<span class="journal_highlight">')\
521 .replace(']', '</span>')
522 .replace(']', '</span>')
522
523
523 action_params_func = lambda :""
524 action_params_func = lambda :""
524
525
525 if callable(action_str[1]):
526 if callable(action_str[1]):
526 action_params_func = action_str[1]
527 action_params_func = action_str[1]
527
528
528 return [literal(action), action_params_func]
529 return [literal(action), action_params_func]
529
530
530 def action_parser_icon(user_log):
531 def action_parser_icon(user_log):
531 action = user_log.action
532 action = user_log.action
532 action_params = None
533 action_params = None
533 x = action.split(':')
534 x = action.split(':')
534
535
535 if len(x) > 1:
536 if len(x) > 1:
536 action, action_params = x
537 action, action_params = x
537
538
538 tmpl = """<img src="%s%s" alt="%s"/>"""
539 tmpl = """<img src="%s%s" alt="%s"/>"""
539 map = {'user_deleted_repo':'database_delete.png',
540 map = {'user_deleted_repo':'database_delete.png',
540 'user_created_repo':'database_add.png',
541 'user_created_repo':'database_add.png',
541 'user_forked_repo':'arrow_divide.png',
542 'user_forked_repo':'arrow_divide.png',
542 'user_updated_repo':'database_edit.png',
543 'user_updated_repo':'database_edit.png',
543 'admin_deleted_repo':'database_delete.png',
544 'admin_deleted_repo':'database_delete.png',
544 'admin_created_repo':'database_add.png',
545 'admin_created_repo':'database_add.png',
545 'admin_forked_repo':'arrow_divide.png',
546 'admin_forked_repo':'arrow_divide.png',
546 'admin_updated_repo':'database_edit.png',
547 'admin_updated_repo':'database_edit.png',
547 'push':'script_add.png',
548 'push':'script_add.png',
548 'push_remote':'connect.png',
549 'push_remote':'connect.png',
549 'pull':'down_16.png',
550 'pull':'down_16.png',
550 'started_following_repo':'heart_add.png',
551 'started_following_repo':'heart_add.png',
551 'stopped_following_repo':'heart_delete.png',
552 'stopped_following_repo':'heart_delete.png',
552 }
553 }
553 return literal(tmpl % ((url('/images/icons/')),
554 return literal(tmpl % ((url('/images/icons/')),
554 map.get(action, action), action))
555 map.get(action, action), action))
555
556
556
557
557 #==============================================================================
558 #==============================================================================
558 # PERMS
559 # PERMS
559 #==============================================================================
560 #==============================================================================
560 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
561 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
561 HasRepoPermissionAny, HasRepoPermissionAll
562 HasRepoPermissionAny, HasRepoPermissionAll
562
563
563 #==============================================================================
564 #==============================================================================
564 # GRAVATAR URL
565 # GRAVATAR URL
565 #==============================================================================
566 #==============================================================================
566
567
567 def gravatar_url(email_address, size=30):
568 def gravatar_url(email_address, size=30):
569 if not str2bool(config['app_conf'].get('use_gravatar')):
570 return "/images/user%s.png" % size
571
568 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
572 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
569 default = 'identicon'
573 default = 'identicon'
570 baseurl_nossl = "http://www.gravatar.com/avatar/"
574 baseurl_nossl = "http://www.gravatar.com/avatar/"
571 baseurl_ssl = "https://secure.gravatar.com/avatar/"
575 baseurl_ssl = "https://secure.gravatar.com/avatar/"
572 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
576 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
573
577
574 if isinstance(email_address, unicode):
578 if isinstance(email_address, unicode):
575 #hashlib crashes on unicode items
579 #hashlib crashes on unicode items
576 email_address = email_address.encode('utf8', 'replace')
580 email_address = email_address.encode('utf8', 'replace')
577 # construct the url
581 # construct the url
578 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
582 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
579 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
583 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
580
584
581 return gravatar_url
585 return gravatar_url
582
586
583
587
584 #==============================================================================
588 #==============================================================================
585 # REPO PAGER
589 # REPO PAGER
586 #==============================================================================
590 #==============================================================================
587 class RepoPage(Page):
591 class RepoPage(Page):
588
592
589 def __init__(self, collection, page=1, items_per_page=20,
593 def __init__(self, collection, page=1, items_per_page=20,
590 item_count=None, url=None, branch_name=None, **kwargs):
594 item_count=None, url=None, branch_name=None, **kwargs):
591
595
592 """Create a "RepoPage" instance. special pager for paging
596 """Create a "RepoPage" instance. special pager for paging
593 repository
597 repository
594 """
598 """
595 self._url_generator = url
599 self._url_generator = url
596
600
597 # Safe the kwargs class-wide so they can be used in the pager() method
601 # Safe the kwargs class-wide so they can be used in the pager() method
598 self.kwargs = kwargs
602 self.kwargs = kwargs
599
603
600 # Save a reference to the collection
604 # Save a reference to the collection
601 self.original_collection = collection
605 self.original_collection = collection
602
606
603 self.collection = collection
607 self.collection = collection
604
608
605 # The self.page is the number of the current page.
609 # The self.page is the number of the current page.
606 # The first page has the number 1!
610 # The first page has the number 1!
607 try:
611 try:
608 self.page = int(page) # make it int() if we get it as a string
612 self.page = int(page) # make it int() if we get it as a string
609 except (ValueError, TypeError):
613 except (ValueError, TypeError):
610 self.page = 1
614 self.page = 1
611
615
612 self.items_per_page = items_per_page
616 self.items_per_page = items_per_page
613
617
614 # Unless the user tells us how many items the collections has
618 # Unless the user tells us how many items the collections has
615 # we calculate that ourselves.
619 # we calculate that ourselves.
616 if item_count is not None:
620 if item_count is not None:
617 self.item_count = item_count
621 self.item_count = item_count
618 else:
622 else:
619 self.item_count = len(self.collection)
623 self.item_count = len(self.collection)
620
624
621 # Compute the number of the first and last available page
625 # Compute the number of the first and last available page
622 if self.item_count > 0:
626 if self.item_count > 0:
623 self.first_page = 1
627 self.first_page = 1
624 self.page_count = ((self.item_count - 1) / self.items_per_page) + 1
628 self.page_count = ((self.item_count - 1) / self.items_per_page) + 1
625 self.last_page = self.first_page + self.page_count - 1
629 self.last_page = self.first_page + self.page_count - 1
626
630
627 # Make sure that the requested page number is the range of valid pages
631 # Make sure that the requested page number is the range of valid pages
628 if self.page > self.last_page:
632 if self.page > self.last_page:
629 self.page = self.last_page
633 self.page = self.last_page
630 elif self.page < self.first_page:
634 elif self.page < self.first_page:
631 self.page = self.first_page
635 self.page = self.first_page
632
636
633 # Note: the number of items on this page can be less than
637 # Note: the number of items on this page can be less than
634 # items_per_page if the last page is not full
638 # items_per_page if the last page is not full
635 self.first_item = max(0, (self.item_count) - (self.page * items_per_page))
639 self.first_item = max(0, (self.item_count) - (self.page * items_per_page))
636 self.last_item = ((self.item_count - 1) - items_per_page * (self.page - 1))
640 self.last_item = ((self.item_count - 1) - items_per_page * (self.page - 1))
637
641
638 iterator = self.collection.get_changesets(start=self.first_item,
642 iterator = self.collection.get_changesets(start=self.first_item,
639 end=self.last_item,
643 end=self.last_item,
640 reverse=True,
644 reverse=True,
641 branch_name=branch_name)
645 branch_name=branch_name)
642 self.items = list(iterator)
646 self.items = list(iterator)
643
647
644 # Links to previous and next page
648 # Links to previous and next page
645 if self.page > self.first_page:
649 if self.page > self.first_page:
646 self.previous_page = self.page - 1
650 self.previous_page = self.page - 1
647 else:
651 else:
648 self.previous_page = None
652 self.previous_page = None
649
653
650 if self.page < self.last_page:
654 if self.page < self.last_page:
651 self.next_page = self.page + 1
655 self.next_page = self.page + 1
652 else:
656 else:
653 self.next_page = None
657 self.next_page = None
654
658
655 # No items available
659 # No items available
656 else:
660 else:
657 self.first_page = None
661 self.first_page = None
658 self.page_count = 0
662 self.page_count = 0
659 self.last_page = None
663 self.last_page = None
660 self.first_item = None
664 self.first_item = None
661 self.last_item = None
665 self.last_item = None
662 self.previous_page = None
666 self.previous_page = None
663 self.next_page = None
667 self.next_page = None
664 self.items = []
668 self.items = []
665
669
666 # This is a subclass of the 'list' type. Initialise the list now.
670 # This is a subclass of the 'list' type. Initialise the list now.
667 list.__init__(self, self.items)
671 list.__init__(self, self.items)
668
672
669
673
670 def safe_unicode(str):
674 def safe_unicode(str):
671 """safe unicode function. In case of UnicodeDecode error we try to return
675 """safe unicode function. In case of UnicodeDecode error we try to return
672 unicode with errors replace, if this failes we return unicode with
676 unicode with errors replace, if this failes we return unicode with
673 string_escape decoding """
677 string_escape decoding """
674
678
675 try:
679 try:
676 u_str = unicode(str)
680 u_str = unicode(str)
677 except UnicodeDecodeError:
681 except UnicodeDecodeError:
678 try:
682 try:
679 u_str = unicode(str, 'utf-8', 'replace')
683 u_str = unicode(str, 'utf-8', 'replace')
680 except UnicodeDecodeError:
684 except UnicodeDecodeError:
681 #incase we have a decode error just represent as byte string
685 #incase we have a decode error just represent as byte string
682 u_str = unicode(str(str).encode('string_escape'))
686 u_str = unicode(str(str).encode('string_escape'))
683
687
684 return u_str
688 return u_str
685
689
686 def changed_tooltip(nodes):
690 def changed_tooltip(nodes):
687 if nodes:
691 if nodes:
688 pref = ': <br/> '
692 pref = ': <br/> '
689 suf = ''
693 suf = ''
690 if len(nodes) > 30:
694 if len(nodes) > 30:
691 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
695 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
692 return literal(pref + '<br/> '.join([x.path.decode('utf-8', 'replace') for x in nodes[:30]]) + suf)
696 return literal(pref + '<br/> '.join([x.path.decode('utf-8', 'replace') for x in nodes[:30]]) + suf)
693 else:
697 else:
694 return ': ' + _('No Files')
698 return ': ' + _('No Files')
General Comments 0
You need to be logged in to leave comments. Login now