##// END OF EJS Templates
#21 added optional flag to disable gravatar, and use local icon
marcink -
r1110:5351a3a3 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,691 +1,695 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 'pull':(_('[pulled] from'), None),
511 'pull':(_('[pulled] from'), None),
511 'started_following_repo':(_('[started following] repository'), None),
512 'started_following_repo':(_('[started following] repository'), None),
512 'stopped_following_repo':(_('[stopped following] repository'), None),
513 'stopped_following_repo':(_('[stopped following] repository'), None),
513 }
514 }
514
515
515 action_str = action_map.get(action, action)
516 action_str = action_map.get(action, action)
516 if feed:
517 if feed:
517 action = action_str[0].replace('[', '').replace(']', '')
518 action = action_str[0].replace('[', '').replace(']', '')
518 else:
519 else:
519 action = action_str[0].replace('[', '<span class="journal_highlight">')\
520 action = action_str[0].replace('[', '<span class="journal_highlight">')\
520 .replace(']', '</span>')
521 .replace(']', '</span>')
521 action_params_func = lambda :""
522 action_params_func = lambda :""
522
523
523 if action_str[1] is not None:
524 if action_str[1] is not None:
524 action_params_func = action_str[1]
525 action_params_func = action_str[1]
525
526
526 return [literal(action), action_params_func]
527 return [literal(action), action_params_func]
527
528
528 def action_parser_icon(user_log):
529 def action_parser_icon(user_log):
529 action = user_log.action
530 action = user_log.action
530 action_params = None
531 action_params = None
531 x = action.split(':')
532 x = action.split(':')
532
533
533 if len(x) > 1:
534 if len(x) > 1:
534 action, action_params = x
535 action, action_params = x
535
536
536 tmpl = """<img src="%s/%s" alt="%s"/>"""
537 tmpl = """<img src="%s/%s" alt="%s"/>"""
537 map = {'user_deleted_repo':'database_delete.png',
538 map = {'user_deleted_repo':'database_delete.png',
538 'user_created_repo':'database_add.png',
539 'user_created_repo':'database_add.png',
539 'user_forked_repo':'arrow_divide.png',
540 'user_forked_repo':'arrow_divide.png',
540 'user_updated_repo':'database_edit.png',
541 'user_updated_repo':'database_edit.png',
541 'admin_deleted_repo':'database_delete.png',
542 'admin_deleted_repo':'database_delete.png',
542 'admin_created_repo':'database_add.png',
543 'admin_created_repo':'database_add.png',
543 'admin_forked_repo':'arrow_divide.png',
544 'admin_forked_repo':'arrow_divide.png',
544 'admin_updated_repo':'database_edit.png',
545 'admin_updated_repo':'database_edit.png',
545 'push':'script_add.png',
546 'push':'script_add.png',
546 'pull':'down_16.png',
547 'pull':'down_16.png',
547 'started_following_repo':'heart_add.png',
548 'started_following_repo':'heart_add.png',
548 'stopped_following_repo':'heart_delete.png',
549 'stopped_following_repo':'heart_delete.png',
549 }
550 }
550 return literal(tmpl % ((url('/images/icons/')),
551 return literal(tmpl % ((url('/images/icons/')),
551 map.get(action, action), action))
552 map.get(action, action), action))
552
553
553
554
554 #==============================================================================
555 #==============================================================================
555 # PERMS
556 # PERMS
556 #==============================================================================
557 #==============================================================================
557 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
558 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
558 HasRepoPermissionAny, HasRepoPermissionAll
559 HasRepoPermissionAny, HasRepoPermissionAll
559
560
560 #==============================================================================
561 #==============================================================================
561 # GRAVATAR URL
562 # GRAVATAR URL
562 #==============================================================================
563 #==============================================================================
563
564
564 def gravatar_url(email_address, size=30):
565 def gravatar_url(email_address, size=30):
566 if not str2bool(config['app_conf'].get('use_gravatar')):
567 return "/images/user%s.png" % size
568
565 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
569 ssl_enabled = 'https' == request.environ.get('wsgi.url_scheme')
566 default = 'identicon'
570 default = 'identicon'
567 baseurl_nossl = "http://www.gravatar.com/avatar/"
571 baseurl_nossl = "http://www.gravatar.com/avatar/"
568 baseurl_ssl = "https://secure.gravatar.com/avatar/"
572 baseurl_ssl = "https://secure.gravatar.com/avatar/"
569 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
573 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
570
574
571 if isinstance(email_address, unicode):
575 if isinstance(email_address, unicode):
572 #hashlib crashes on unicode items
576 #hashlib crashes on unicode items
573 email_address = email_address.encode('utf8', 'replace')
577 email_address = email_address.encode('utf8', 'replace')
574 # construct the url
578 # construct the url
575 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
579 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
576 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
580 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
577
581
578 return gravatar_url
582 return gravatar_url
579
583
580
584
581 #==============================================================================
585 #==============================================================================
582 # REPO PAGER
586 # REPO PAGER
583 #==============================================================================
587 #==============================================================================
584 class RepoPage(Page):
588 class RepoPage(Page):
585
589
586 def __init__(self, collection, page=1, items_per_page=20,
590 def __init__(self, collection, page=1, items_per_page=20,
587 item_count=None, url=None, branch_name=None, **kwargs):
591 item_count=None, url=None, branch_name=None, **kwargs):
588
592
589 """Create a "RepoPage" instance. special pager for paging
593 """Create a "RepoPage" instance. special pager for paging
590 repository
594 repository
591 """
595 """
592 self._url_generator = url
596 self._url_generator = url
593
597
594 # Safe the kwargs class-wide so they can be used in the pager() method
598 # Safe the kwargs class-wide so they can be used in the pager() method
595 self.kwargs = kwargs
599 self.kwargs = kwargs
596
600
597 # Save a reference to the collection
601 # Save a reference to the collection
598 self.original_collection = collection
602 self.original_collection = collection
599
603
600 self.collection = collection
604 self.collection = collection
601
605
602 # The self.page is the number of the current page.
606 # The self.page is the number of the current page.
603 # The first page has the number 1!
607 # The first page has the number 1!
604 try:
608 try:
605 self.page = int(page) # make it int() if we get it as a string
609 self.page = int(page) # make it int() if we get it as a string
606 except (ValueError, TypeError):
610 except (ValueError, TypeError):
607 self.page = 1
611 self.page = 1
608
612
609 self.items_per_page = items_per_page
613 self.items_per_page = items_per_page
610
614
611 # Unless the user tells us how many items the collections has
615 # Unless the user tells us how many items the collections has
612 # we calculate that ourselves.
616 # we calculate that ourselves.
613 if item_count is not None:
617 if item_count is not None:
614 self.item_count = item_count
618 self.item_count = item_count
615 else:
619 else:
616 self.item_count = len(self.collection)
620 self.item_count = len(self.collection)
617
621
618 # Compute the number of the first and last available page
622 # Compute the number of the first and last available page
619 if self.item_count > 0:
623 if self.item_count > 0:
620 self.first_page = 1
624 self.first_page = 1
621 self.page_count = ((self.item_count - 1) / self.items_per_page) + 1
625 self.page_count = ((self.item_count - 1) / self.items_per_page) + 1
622 self.last_page = self.first_page + self.page_count - 1
626 self.last_page = self.first_page + self.page_count - 1
623
627
624 # Make sure that the requested page number is the range of valid pages
628 # Make sure that the requested page number is the range of valid pages
625 if self.page > self.last_page:
629 if self.page > self.last_page:
626 self.page = self.last_page
630 self.page = self.last_page
627 elif self.page < self.first_page:
631 elif self.page < self.first_page:
628 self.page = self.first_page
632 self.page = self.first_page
629
633
630 # Note: the number of items on this page can be less than
634 # Note: the number of items on this page can be less than
631 # items_per_page if the last page is not full
635 # items_per_page if the last page is not full
632 self.first_item = max(0, (self.item_count) - (self.page * items_per_page))
636 self.first_item = max(0, (self.item_count) - (self.page * items_per_page))
633 self.last_item = ((self.item_count - 1) - items_per_page * (self.page - 1))
637 self.last_item = ((self.item_count - 1) - items_per_page * (self.page - 1))
634
638
635 iterator = self.collection.get_changesets(start=self.first_item,
639 iterator = self.collection.get_changesets(start=self.first_item,
636 end=self.last_item,
640 end=self.last_item,
637 reverse=True,
641 reverse=True,
638 branch_name=branch_name)
642 branch_name=branch_name)
639 self.items = list(iterator)
643 self.items = list(iterator)
640
644
641 # Links to previous and next page
645 # Links to previous and next page
642 if self.page > self.first_page:
646 if self.page > self.first_page:
643 self.previous_page = self.page - 1
647 self.previous_page = self.page - 1
644 else:
648 else:
645 self.previous_page = None
649 self.previous_page = None
646
650
647 if self.page < self.last_page:
651 if self.page < self.last_page:
648 self.next_page = self.page + 1
652 self.next_page = self.page + 1
649 else:
653 else:
650 self.next_page = None
654 self.next_page = None
651
655
652 # No items available
656 # No items available
653 else:
657 else:
654 self.first_page = None
658 self.first_page = None
655 self.page_count = 0
659 self.page_count = 0
656 self.last_page = None
660 self.last_page = None
657 self.first_item = None
661 self.first_item = None
658 self.last_item = None
662 self.last_item = None
659 self.previous_page = None
663 self.previous_page = None
660 self.next_page = None
664 self.next_page = None
661 self.items = []
665 self.items = []
662
666
663 # This is a subclass of the 'list' type. Initialise the list now.
667 # This is a subclass of the 'list' type. Initialise the list now.
664 list.__init__(self, self.items)
668 list.__init__(self, self.items)
665
669
666
670
667 def safe_unicode(str):
671 def safe_unicode(str):
668 """safe unicode function. In case of UnicodeDecode error we try to return
672 """safe unicode function. In case of UnicodeDecode error we try to return
669 unicode with errors replace, if this failes we return unicode with
673 unicode with errors replace, if this failes we return unicode with
670 string_escape decoding """
674 string_escape decoding """
671
675
672 try:
676 try:
673 u_str = unicode(str)
677 u_str = unicode(str)
674 except UnicodeDecodeError:
678 except UnicodeDecodeError:
675 try:
679 try:
676 u_str = unicode(str, 'utf-8', 'replace')
680 u_str = unicode(str, 'utf-8', 'replace')
677 except UnicodeDecodeError:
681 except UnicodeDecodeError:
678 #incase we have a decode error just represent as byte string
682 #incase we have a decode error just represent as byte string
679 u_str = unicode(str(str).encode('string_escape'))
683 u_str = unicode(str(str).encode('string_escape'))
680
684
681 return u_str
685 return u_str
682
686
683 def changed_tooltip(nodes):
687 def changed_tooltip(nodes):
684 if nodes:
688 if nodes:
685 pref = ': <br/> '
689 pref = ': <br/> '
686 suf = ''
690 suf = ''
687 if len(nodes) > 30:
691 if len(nodes) > 30:
688 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
692 suf = '<br/>' + _(' and %s more') % (len(nodes) - 30)
689 return literal(pref + '<br/> '.join([x.path.decode('utf-8', 'replace') for x in nodes[:30]]) + suf)
693 return literal(pref + '<br/> '.join([x.path.decode('utf-8', 'replace') for x in nodes[:30]]) + suf)
690 else:
694 else:
691 return ': ' + _('No Files')
695 return ': ' + _('No Files')
General Comments 0
You need to be logged in to leave comments. Login now