##// END OF EJS Templates
Bumped sqlalchemy version to 0.7, replaced timerproxy with new event system for sqlalchemy....
marcink -
r1360:1f47adeb beta
parent child Browse files
Show More
@@ -1,233 +1,233 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20
20
21 #smtp_server = mail.server.com
21 #smtp_server = mail.server.com
22 #smtp_username =
22 #smtp_username =
23 #smtp_password =
23 #smtp_password =
24 #smtp_port =
24 #smtp_port =
25 #smtp_use_tls = false
25 #smtp_use_tls = false
26 #smtp_use_ssl = true
26 #smtp_use_ssl = true
27
27
28 [server:main]
28 [server:main]
29 ##nr of threads to spawn
29 ##nr of threads to spawn
30 threadpool_workers = 5
30 threadpool_workers = 5
31
31
32 ##max request before thread respawn
32 ##max request before thread respawn
33 threadpool_max_requests = 6
33 threadpool_max_requests = 6
34
34
35 ##option to use threads of process
35 ##option to use threads of process
36 use_threadpool = true
36 use_threadpool = true
37
37
38 use = egg:Paste#http
38 use = egg:Paste#http
39 host = 0.0.0.0
39 host = 0.0.0.0
40 port = 5000
40 port = 5000
41
41
42 [app:main]
42 [app:main]
43 use = egg:rhodecode
43 use = egg:rhodecode
44 full_stack = true
44 full_stack = true
45 static_files = true
45 static_files = true
46 lang=en
46 lang=en
47 cache_dir = %(here)s/data
47 cache_dir = %(here)s/data
48 index_dir = %(here)s/data/index
48 index_dir = %(here)s/data/index
49 app_instance_uuid = develop
49 app_instance_uuid = develop
50 cut_off_limit = 256000
50 cut_off_limit = 256000
51 force_https = false
51 force_https = false
52 commit_parse_limit = 25
52 commit_parse_limit = 25
53 use_gravatar = true
53 use_gravatar = true
54
54
55 ####################################
55 ####################################
56 ### CELERY CONFIG ####
56 ### CELERY CONFIG ####
57 ####################################
57 ####################################
58 use_celery = false
58 use_celery = false
59 broker.host = localhost
59 broker.host = localhost
60 broker.vhost = rabbitmqhost
60 broker.vhost = rabbitmqhost
61 broker.port = 5672
61 broker.port = 5672
62 broker.user = rabbitmq
62 broker.user = rabbitmq
63 broker.password = qweqwe
63 broker.password = qweqwe
64
64
65 celery.imports = rhodecode.lib.celerylib.tasks
65 celery.imports = rhodecode.lib.celerylib.tasks
66
66
67 celery.result.backend = amqp
67 celery.result.backend = amqp
68 celery.result.dburi = amqp://
68 celery.result.dburi = amqp://
69 celery.result.serialier = json
69 celery.result.serialier = json
70
70
71 #celery.send.task.error.emails = true
71 #celery.send.task.error.emails = true
72 #celery.amqp.task.result.expires = 18000
72 #celery.amqp.task.result.expires = 18000
73
73
74 celeryd.concurrency = 2
74 celeryd.concurrency = 2
75 #celeryd.log.file = celeryd.log
75 #celeryd.log.file = celeryd.log
76 celeryd.log.level = debug
76 celeryd.log.level = debug
77 celeryd.max.tasks.per.child = 1
77 celeryd.max.tasks.per.child = 1
78
78
79 #tasks will never be sent to the queue, but executed locally instead.
79 #tasks will never be sent to the queue, but executed locally instead.
80 celery.always.eager = false
80 celery.always.eager = false
81
81
82 ####################################
82 ####################################
83 ### BEAKER CACHE ####
83 ### BEAKER CACHE ####
84 ####################################
84 ####################################
85 beaker.cache.data_dir=%(here)s/data/cache/data
85 beaker.cache.data_dir=%(here)s/data/cache/data
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
87
87
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
89
89
90 beaker.cache.super_short_term.type=memory
90 beaker.cache.super_short_term.type=memory
91 beaker.cache.super_short_term.expire=10
91 beaker.cache.super_short_term.expire=10
92
92
93 beaker.cache.short_term.type=memory
93 beaker.cache.short_term.type=memory
94 beaker.cache.short_term.expire=60
94 beaker.cache.short_term.expire=60
95
95
96 beaker.cache.long_term.type=memory
96 beaker.cache.long_term.type=memory
97 beaker.cache.long_term.expire=36000
97 beaker.cache.long_term.expire=36000
98
98
99 beaker.cache.sql_cache_short.type=memory
99 beaker.cache.sql_cache_short.type=memory
100 beaker.cache.sql_cache_short.expire=10
100 beaker.cache.sql_cache_short.expire=10
101
101
102 beaker.cache.sql_cache_med.type=memory
102 beaker.cache.sql_cache_med.type=memory
103 beaker.cache.sql_cache_med.expire=360
103 beaker.cache.sql_cache_med.expire=360
104
104
105 beaker.cache.sql_cache_long.type=file
105 beaker.cache.sql_cache_long.type=file
106 beaker.cache.sql_cache_long.expire=3600
106 beaker.cache.sql_cache_long.expire=3600
107
107
108 ####################################
108 ####################################
109 ### BEAKER SESSION ####
109 ### BEAKER SESSION ####
110 ####################################
110 ####################################
111 ## Type of storage used for the session, current types are
111 ## Type of storage used for the session, current types are
112 ## dbm, file, memcached, database, and memory.
112 ## dbm, file, memcached, database, and memory.
113 ## The storage uses the Container API
113 ## The storage uses the Container API
114 ##that is also used by the cache system.
114 ##that is also used by the cache system.
115 beaker.session.type = file
115 beaker.session.type = file
116
116
117 beaker.session.key = rhodecode
117 beaker.session.key = rhodecode
118 beaker.session.secret = g654dcno0-9873jhgfreyu
118 beaker.session.secret = g654dcno0-9873jhgfreyu
119 beaker.session.timeout = 36000
119 beaker.session.timeout = 36000
120
120
121 ##auto save the session to not to use .save()
121 ##auto save the session to not to use .save()
122 beaker.session.auto = False
122 beaker.session.auto = False
123
123
124 ##true exire at browser close
124 ##true exire at browser close
125 #beaker.session.cookie_expires = 3600
125 #beaker.session.cookie_expires = 3600
126
126
127
127
128 ################################################################################
128 ################################################################################
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
131 ## execute malicious code after an exception is raised. ##
131 ## execute malicious code after an exception is raised. ##
132 ################################################################################
132 ################################################################################
133 #set debug = false
133 #set debug = false
134
134
135 ##################################
135 ##################################
136 ### LOGVIEW CONFIG ###
136 ### LOGVIEW CONFIG ###
137 ##################################
137 ##################################
138 logview.sqlalchemy = #faa
138 logview.sqlalchemy = #faa
139 logview.pylons.templating = #bfb
139 logview.pylons.templating = #bfb
140 logview.pylons.util = #eee
140 logview.pylons.util = #eee
141
141
142 #########################################################
142 #########################################################
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
144 #########################################################
144 #########################################################
145 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
145 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
146 #sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
146 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
147 sqlalchemy.db1.echo = True
147 sqlalchemy.db1.echo = false
148 sqlalchemy.db1.pool_recycle = 3600
148 sqlalchemy.db1.pool_recycle = 3600
149 sqlalchemy.convert_unicode = true
149 sqlalchemy.convert_unicode = true
150
150
151 ################################
151 ################################
152 ### LOGGING CONFIGURATION ####
152 ### LOGGING CONFIGURATION ####
153 ################################
153 ################################
154 [loggers]
154 [loggers]
155 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
155 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
156
156
157 [handlers]
157 [handlers]
158 keys = console, console_sql
158 keys = console, console_sql
159
159
160 [formatters]
160 [formatters]
161 keys = generic, color_formatter, color_formatter_sql
161 keys = generic, color_formatter, color_formatter_sql
162
162
163 #############
163 #############
164 ## LOGGERS ##
164 ## LOGGERS ##
165 #############
165 #############
166 [logger_root]
166 [logger_root]
167 level = NOTSET
167 level = NOTSET
168 handlers = console
168 handlers = console
169
169
170 [logger_routes]
170 [logger_routes]
171 level = DEBUG
171 level = DEBUG
172 handlers =
172 handlers =
173 qualname = routes.middleware
173 qualname = routes.middleware
174 # "level = DEBUG" logs the route matched and routing variables.
174 # "level = DEBUG" logs the route matched and routing variables.
175 propagate = 1
175 propagate = 1
176
176
177 [logger_beaker]
177 [logger_beaker]
178 level = DEBUG
178 level = DEBUG
179 handlers =
179 handlers =
180 qualname = beaker.container
180 qualname = beaker.container
181 propagate = 1
181 propagate = 1
182
182
183 [logger_templates]
183 [logger_templates]
184 level = INFO
184 level = INFO
185 handlers =
185 handlers =
186 qualname = pylons.templating
186 qualname = pylons.templating
187 propagate = 1
187 propagate = 1
188
188
189 [logger_rhodecode]
189 [logger_rhodecode]
190 level = DEBUG
190 level = DEBUG
191 handlers =
191 handlers =
192 qualname = rhodecode
192 qualname = rhodecode
193 propagate = 1
193 propagate = 1
194
194
195 [logger_sqlalchemy]
195 [logger_sqlalchemy]
196 level = INFO
196 level = INFO
197 handlers = console_sql
197 handlers = console_sql
198 qualname = sqlalchemy.engine
198 qualname = sqlalchemy.engine
199 propagate = 0
199 propagate = 0
200
200
201 ##############
201 ##############
202 ## HANDLERS ##
202 ## HANDLERS ##
203 ##############
203 ##############
204
204
205 [handler_console]
205 [handler_console]
206 class = StreamHandler
206 class = StreamHandler
207 args = (sys.stderr,)
207 args = (sys.stderr,)
208 level = NOTSET
208 level = DEBUG
209 formatter = color_formatter
209 formatter = color_formatter
210
210
211 [handler_console_sql]
211 [handler_console_sql]
212 class = StreamHandler
212 class = StreamHandler
213 args = (sys.stderr,)
213 args = (sys.stderr,)
214 level = NOTSET
214 level = DEBUG
215 formatter = color_formatter_sql
215 formatter = color_formatter_sql
216
216
217 ################
217 ################
218 ## FORMATTERS ##
218 ## FORMATTERS ##
219 ################
219 ################
220
220
221 [formatter_generic]
221 [formatter_generic]
222 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
222 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
223 datefmt = %Y-%m-%d %H:%M:%S
223 datefmt = %Y-%m-%d %H:%M:%S
224
224
225 [formatter_color_formatter]
225 [formatter_color_formatter]
226 class=rhodecode.lib.colored_formatter.ColorFormatter
226 class=rhodecode.lib.colored_formatter.ColorFormatter
227 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
227 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
228 datefmt = %Y-%m-%d %H:%M:%S
228 datefmt = %Y-%m-%d %H:%M:%S
229
229
230 [formatter_color_formatter_sql]
230 [formatter_color_formatter_sql]
231 class=rhodecode.lib.colored_formatter.ColorFormatterSql
231 class=rhodecode.lib.colored_formatter.ColorFormatterSql
232 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
232 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
233 datefmt = %Y-%m-%d %H:%M:%S
233 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,233 +1,233 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20
20
21 #smtp_server = mail.server.com
21 #smtp_server = mail.server.com
22 #smtp_username =
22 #smtp_username =
23 #smtp_password =
23 #smtp_password =
24 #smtp_port =
24 #smtp_port =
25 #smtp_use_tls = false
25 #smtp_use_tls = false
26 #smtp_use_ssl = true
26 #smtp_use_ssl = true
27
27
28 [server:main]
28 [server:main]
29 ##nr of threads to spawn
29 ##nr of threads to spawn
30 threadpool_workers = 5
30 threadpool_workers = 5
31
31
32 ##max request before thread respawn
32 ##max request before thread respawn
33 threadpool_max_requests = 10
33 threadpool_max_requests = 10
34
34
35 ##option to use threads of process
35 ##option to use threads of process
36 use_threadpool = true
36 use_threadpool = true
37
37
38 use = egg:Paste#http
38 use = egg:Paste#http
39 host = 127.0.0.1
39 host = 127.0.0.1
40 port = 8001
40 port = 8001
41
41
42 [app:main]
42 [app:main]
43 use = egg:rhodecode
43 use = egg:rhodecode
44 full_stack = true
44 full_stack = true
45 static_files = true
45 static_files = true
46 lang=en
46 lang=en
47 cache_dir = %(here)s/data
47 cache_dir = %(here)s/data
48 index_dir = %(here)s/data/index
48 index_dir = %(here)s/data/index
49 app_instance_uuid = prod1234
49 app_instance_uuid = prod1234
50 cut_off_limit = 256000
50 cut_off_limit = 256000
51 force_https = false
51 force_https = false
52 commit_parse_limit = 50
52 commit_parse_limit = 50
53 use_gravatar = true
53 use_gravatar = true
54
54
55 ####################################
55 ####################################
56 ### CELERY CONFIG ####
56 ### CELERY CONFIG ####
57 ####################################
57 ####################################
58 use_celery = false
58 use_celery = false
59 broker.host = localhost
59 broker.host = localhost
60 broker.vhost = rabbitmqhost
60 broker.vhost = rabbitmqhost
61 broker.port = 5672
61 broker.port = 5672
62 broker.user = rabbitmq
62 broker.user = rabbitmq
63 broker.password = qweqwe
63 broker.password = qweqwe
64
64
65 celery.imports = rhodecode.lib.celerylib.tasks
65 celery.imports = rhodecode.lib.celerylib.tasks
66
66
67 celery.result.backend = amqp
67 celery.result.backend = amqp
68 celery.result.dburi = amqp://
68 celery.result.dburi = amqp://
69 celery.result.serialier = json
69 celery.result.serialier = json
70
70
71 #celery.send.task.error.emails = true
71 #celery.send.task.error.emails = true
72 #celery.amqp.task.result.expires = 18000
72 #celery.amqp.task.result.expires = 18000
73
73
74 celeryd.concurrency = 2
74 celeryd.concurrency = 2
75 #celeryd.log.file = celeryd.log
75 #celeryd.log.file = celeryd.log
76 celeryd.log.level = debug
76 celeryd.log.level = debug
77 celeryd.max.tasks.per.child = 1
77 celeryd.max.tasks.per.child = 1
78
78
79 #tasks will never be sent to the queue, but executed locally instead.
79 #tasks will never be sent to the queue, but executed locally instead.
80 celery.always.eager = false
80 celery.always.eager = false
81
81
82 ####################################
82 ####################################
83 ### BEAKER CACHE ####
83 ### BEAKER CACHE ####
84 ####################################
84 ####################################
85 beaker.cache.data_dir=%(here)s/data/cache/data
85 beaker.cache.data_dir=%(here)s/data/cache/data
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
87
87
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
89
89
90 beaker.cache.super_short_term.type=memory
90 beaker.cache.super_short_term.type=memory
91 beaker.cache.super_short_term.expire=10
91 beaker.cache.super_short_term.expire=10
92
92
93 beaker.cache.short_term.type=memory
93 beaker.cache.short_term.type=memory
94 beaker.cache.short_term.expire=60
94 beaker.cache.short_term.expire=60
95
95
96 beaker.cache.long_term.type=memory
96 beaker.cache.long_term.type=memory
97 beaker.cache.long_term.expire=36000
97 beaker.cache.long_term.expire=36000
98
98
99 beaker.cache.sql_cache_short.type=memory
99 beaker.cache.sql_cache_short.type=memory
100 beaker.cache.sql_cache_short.expire=10
100 beaker.cache.sql_cache_short.expire=10
101
101
102 beaker.cache.sql_cache_med.type=memory
102 beaker.cache.sql_cache_med.type=memory
103 beaker.cache.sql_cache_med.expire=360
103 beaker.cache.sql_cache_med.expire=360
104
104
105 beaker.cache.sql_cache_long.type=file
105 beaker.cache.sql_cache_long.type=file
106 beaker.cache.sql_cache_long.expire=3600
106 beaker.cache.sql_cache_long.expire=3600
107
107
108 ####################################
108 ####################################
109 ### BEAKER SESSION ####
109 ### BEAKER SESSION ####
110 ####################################
110 ####################################
111 ## Type of storage used for the session, current types are
111 ## Type of storage used for the session, current types are
112 ## dbm, file, memcached, database, and memory.
112 ## dbm, file, memcached, database, and memory.
113 ## The storage uses the Container API
113 ## The storage uses the Container API
114 ##that is also used by the cache system.
114 ##that is also used by the cache system.
115 beaker.session.type = file
115 beaker.session.type = file
116
116
117 beaker.session.key = rhodecode
117 beaker.session.key = rhodecode
118 beaker.session.secret = g654dcno0-9873jhgfreyu
118 beaker.session.secret = g654dcno0-9873jhgfreyu
119 beaker.session.timeout = 36000
119 beaker.session.timeout = 36000
120
120
121 ##auto save the session to not to use .save()
121 ##auto save the session to not to use .save()
122 beaker.session.auto = False
122 beaker.session.auto = False
123
123
124 ##true exire at browser close
124 ##true exire at browser close
125 #beaker.session.cookie_expires = 3600
125 #beaker.session.cookie_expires = 3600
126
126
127
127
128 ################################################################################
128 ################################################################################
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
131 ## execute malicious code after an exception is raised. ##
131 ## execute malicious code after an exception is raised. ##
132 ################################################################################
132 ################################################################################
133 set debug = false
133 set debug = false
134
134
135 ##################################
135 ##################################
136 ### LOGVIEW CONFIG ###
136 ### LOGVIEW CONFIG ###
137 ##################################
137 ##################################
138 logview.sqlalchemy = #faa
138 logview.sqlalchemy = #faa
139 logview.pylons.templating = #bfb
139 logview.pylons.templating = #bfb
140 logview.pylons.util = #eee
140 logview.pylons.util = #eee
141
141
142 #########################################################
142 #########################################################
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
144 #########################################################
144 #########################################################
145 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
145 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
146 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
146 sqlalchemy.db1.url = postgresql://postgres:qwe@localhost/rhodecode
147 sqlalchemy.db1.echo = True
147 sqlalchemy.db1.echo = false
148 sqlalchemy.db1.pool_recycle = 3600
148 sqlalchemy.db1.pool_recycle = 3600
149 sqlalchemy.convert_unicode = true
149 sqlalchemy.convert_unicode = true
150
150
151 ################################
151 ################################
152 ### LOGGING CONFIGURATION ####
152 ### LOGGING CONFIGURATION ####
153 ################################
153 ################################
154 [loggers]
154 [loggers]
155 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
155 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
156
156
157 [handlers]
157 [handlers]
158 keys = console, console_sql
158 keys = console, console_sql
159
159
160 [formatters]
160 [formatters]
161 keys = generic, color_formatter, color_formatter_sql
161 keys = generic, color_formatter, color_formatter_sql
162
162
163 #############
163 #############
164 ## LOGGERS ##
164 ## LOGGERS ##
165 #############
165 #############
166 [logger_root]
166 [logger_root]
167 level = NOTSET
167 level = NOTSET
168 handlers = console
168 handlers = console
169
169
170 [logger_routes]
170 [logger_routes]
171 level = DEBUG
171 level = DEBUG
172 handlers =
172 handlers =
173 qualname = routes.middleware
173 qualname = routes.middleware
174 # "level = DEBUG" logs the route matched and routing variables.
174 # "level = DEBUG" logs the route matched and routing variables.
175 propagate = 1
175 propagate = 1
176
176
177 [logger_beaker]
177 [logger_beaker]
178 level = DEBUG
178 level = DEBUG
179 handlers =
179 handlers =
180 qualname = beaker.container
180 qualname = beaker.container
181 propagate = 1
181 propagate = 1
182
182
183 [logger_templates]
183 [logger_templates]
184 level = INFO
184 level = INFO
185 handlers =
185 handlers =
186 qualname = pylons.templating
186 qualname = pylons.templating
187 propagate = 1
187 propagate = 1
188
188
189 [logger_rhodecode]
189 [logger_rhodecode]
190 level = DEBUG
190 level = DEBUG
191 handlers =
191 handlers =
192 qualname = rhodecode
192 qualname = rhodecode
193 propagate = 1
193 propagate = 1
194
194
195 [logger_sqlalchemy]
195 [logger_sqlalchemy]
196 level = INFO
196 level = INFO
197 handlers = console_sql
197 handlers = console_sql
198 qualname = sqlalchemy.engine
198 qualname = sqlalchemy.engine
199 propagate = 0
199 propagate = 0
200
200
201 ##############
201 ##############
202 ## HANDLERS ##
202 ## HANDLERS ##
203 ##############
203 ##############
204
204
205 [handler_console]
205 [handler_console]
206 class = StreamHandler
206 class = StreamHandler
207 args = (sys.stderr,)
207 args = (sys.stderr,)
208 level = INFO
208 level = INFO
209 formatter = color_formatter
209 formatter = color_formatter
210
210
211 [handler_console_sql]
211 [handler_console_sql]
212 class = StreamHandler
212 class = StreamHandler
213 args = (sys.stderr,)
213 args = (sys.stderr,)
214 level = WARN
214 level = WARN
215 formatter = color_formatter_sql
215 formatter = color_formatter_sql
216
216
217 ################
217 ################
218 ## FORMATTERS ##
218 ## FORMATTERS ##
219 ################
219 ################
220
220
221 [formatter_generic]
221 [formatter_generic]
222 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
222 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
223 datefmt = %Y-%m-%d %H:%M:%S
223 datefmt = %Y-%m-%d %H:%M:%S
224
224
225 [formatter_color_formatter]
225 [formatter_color_formatter]
226 class=rhodecode.lib.colored_formatter.ColorFormatter
226 class=rhodecode.lib.colored_formatter.ColorFormatter
227 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
227 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
228 datefmt = %Y-%m-%d %H:%M:%S
228 datefmt = %Y-%m-%d %H:%M:%S
229
229
230 [formatter_color_formatter_sql]
230 [formatter_color_formatter_sql]
231 class=rhodecode.lib.colored_formatter.ColorFormatterSql
231 class=rhodecode.lib.colored_formatter.ColorFormatterSql
232 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
232 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
233 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
233 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,232 +1,232 b''
1 ################################################################################
1 ################################################################################
2 ################################################################################
2 ################################################################################
3 # RhodeCode - Pylons environment configuration #
3 # RhodeCode - Pylons environment configuration #
4 # #
4 # #
5 # The %(here)s variable will be replaced with the parent directory of this file#
5 # The %(here)s variable will be replaced with the parent directory of this file#
6 ################################################################################
6 ################################################################################
7
7
8 [DEFAULT]
8 [DEFAULT]
9 debug = true
9 debug = true
10 pdebug = false
10 pdebug = false
11 ################################################################################
11 ################################################################################
12 ## Uncomment and replace with the address which should receive ##
12 ## Uncomment and replace with the address which should receive ##
13 ## any error reports after application crash ##
13 ## any error reports after application crash ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
14 ## Additionally those settings will be used by RhodeCode mailing system ##
15 ################################################################################
15 ################################################################################
16 #email_to = admin@localhost
16 #email_to = admin@localhost
17 #error_email_from = paste_error@localhost
17 #error_email_from = paste_error@localhost
18 #app_email_from = rhodecode-noreply@localhost
18 #app_email_from = rhodecode-noreply@localhost
19 #error_message =
19 #error_message =
20
20
21 #smtp_server = mail.server.com
21 #smtp_server = mail.server.com
22 #smtp_username =
22 #smtp_username =
23 #smtp_password =
23 #smtp_password =
24 #smtp_port =
24 #smtp_port =
25 #smtp_use_tls = false
25 #smtp_use_tls = false
26 #smtp_use_ssl = true
26 #smtp_use_ssl = true
27
27
28 [server:main]
28 [server:main]
29 ##nr of threads to spawn
29 ##nr of threads to spawn
30 threadpool_workers = 5
30 threadpool_workers = 5
31
31
32 ##max request before thread respawn
32 ##max request before thread respawn
33 threadpool_max_requests = 10
33 threadpool_max_requests = 10
34
34
35 ##option to use threads of process
35 ##option to use threads of process
36 use_threadpool = true
36 use_threadpool = true
37
37
38 use = egg:Paste#http
38 use = egg:Paste#http
39 host = 127.0.0.1
39 host = 127.0.0.1
40 port = 5000
40 port = 5000
41
41
42 [app:main]
42 [app:main]
43 use = egg:rhodecode
43 use = egg:rhodecode
44 full_stack = true
44 full_stack = true
45 static_files = true
45 static_files = true
46 lang=en
46 lang=en
47 cache_dir = %(here)s/data
47 cache_dir = %(here)s/data
48 index_dir = %(here)s/data/index
48 index_dir = %(here)s/data/index
49 app_instance_uuid = ${app_instance_uuid}
49 app_instance_uuid = ${app_instance_uuid}
50 cut_off_limit = 256000
50 cut_off_limit = 256000
51 force_https = false
51 force_https = false
52 commit_parse_limit = 50
52 commit_parse_limit = 50
53 use_gravatar = true
53 use_gravatar = true
54
54
55 ####################################
55 ####################################
56 ### CELERY CONFIG ####
56 ### CELERY CONFIG ####
57 ####################################
57 ####################################
58 use_celery = false
58 use_celery = false
59 broker.host = localhost
59 broker.host = localhost
60 broker.vhost = rabbitmqhost
60 broker.vhost = rabbitmqhost
61 broker.port = 5672
61 broker.port = 5672
62 broker.user = rabbitmq
62 broker.user = rabbitmq
63 broker.password = qweqwe
63 broker.password = qweqwe
64
64
65 celery.imports = rhodecode.lib.celerylib.tasks
65 celery.imports = rhodecode.lib.celerylib.tasks
66
66
67 celery.result.backend = amqp
67 celery.result.backend = amqp
68 celery.result.dburi = amqp://
68 celery.result.dburi = amqp://
69 celery.result.serialier = json
69 celery.result.serialier = json
70
70
71 #celery.send.task.error.emails = true
71 #celery.send.task.error.emails = true
72 #celery.amqp.task.result.expires = 18000
72 #celery.amqp.task.result.expires = 18000
73
73
74 celeryd.concurrency = 2
74 celeryd.concurrency = 2
75 #celeryd.log.file = celeryd.log
75 #celeryd.log.file = celeryd.log
76 celeryd.log.level = debug
76 celeryd.log.level = debug
77 celeryd.max.tasks.per.child = 1
77 celeryd.max.tasks.per.child = 1
78
78
79 #tasks will never be sent to the queue, but executed locally instead.
79 #tasks will never be sent to the queue, but executed locally instead.
80 celery.always.eager = false
80 celery.always.eager = false
81
81
82 ####################################
82 ####################################
83 ### BEAKER CACHE ####
83 ### BEAKER CACHE ####
84 ####################################
84 ####################################
85 beaker.cache.data_dir=%(here)s/data/cache/data
85 beaker.cache.data_dir=%(here)s/data/cache/data
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
86 beaker.cache.lock_dir=%(here)s/data/cache/lock
87
87
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
88 beaker.cache.regions=super_short_term,short_term,long_term,sql_cache_short,sql_cache_med,sql_cache_long
89
89
90 beaker.cache.super_short_term.type=memory
90 beaker.cache.super_short_term.type=memory
91 beaker.cache.super_short_term.expire=10
91 beaker.cache.super_short_term.expire=10
92
92
93 beaker.cache.short_term.type=memory
93 beaker.cache.short_term.type=memory
94 beaker.cache.short_term.expire=60
94 beaker.cache.short_term.expire=60
95
95
96 beaker.cache.long_term.type=memory
96 beaker.cache.long_term.type=memory
97 beaker.cache.long_term.expire=36000
97 beaker.cache.long_term.expire=36000
98
98
99 beaker.cache.sql_cache_short.type=memory
99 beaker.cache.sql_cache_short.type=memory
100 beaker.cache.sql_cache_short.expire=10
100 beaker.cache.sql_cache_short.expire=10
101
101
102 beaker.cache.sql_cache_med.type=memory
102 beaker.cache.sql_cache_med.type=memory
103 beaker.cache.sql_cache_med.expire=360
103 beaker.cache.sql_cache_med.expire=360
104
104
105 beaker.cache.sql_cache_long.type=file
105 beaker.cache.sql_cache_long.type=file
106 beaker.cache.sql_cache_long.expire=3600
106 beaker.cache.sql_cache_long.expire=3600
107
107
108 ####################################
108 ####################################
109 ### BEAKER SESSION ####
109 ### BEAKER SESSION ####
110 ####################################
110 ####################################
111 ## Type of storage used for the session, current types are
111 ## Type of storage used for the session, current types are
112 ## dbm, file, memcached, database, and memory.
112 ## dbm, file, memcached, database, and memory.
113 ## The storage uses the Container API
113 ## The storage uses the Container API
114 ##that is also used by the cache system.
114 ##that is also used by the cache system.
115 beaker.session.type = file
115 beaker.session.type = file
116
116
117 beaker.session.key = rhodecode
117 beaker.session.key = rhodecode
118 beaker.session.secret = ${app_instance_secret}
118 beaker.session.secret = ${app_instance_secret}
119 beaker.session.timeout = 36000
119 beaker.session.timeout = 36000
120
120
121 ##auto save the session to not to use .save()
121 ##auto save the session to not to use .save()
122 beaker.session.auto = False
122 beaker.session.auto = False
123
123
124 ##true exire at browser close
124 ##true exire at browser close
125 #beaker.session.cookie_expires = 3600
125 #beaker.session.cookie_expires = 3600
126
126
127
127
128 ################################################################################
128 ################################################################################
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
129 ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
130 ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ##
131 ## execute malicious code after an exception is raised. ##
131 ## execute malicious code after an exception is raised. ##
132 ################################################################################
132 ################################################################################
133 set debug = false
133 set debug = false
134
134
135 ##################################
135 ##################################
136 ### LOGVIEW CONFIG ###
136 ### LOGVIEW CONFIG ###
137 ##################################
137 ##################################
138 logview.sqlalchemy = #faa
138 logview.sqlalchemy = #faa
139 logview.pylons.templating = #bfb
139 logview.pylons.templating = #bfb
140 logview.pylons.util = #eee
140 logview.pylons.util = #eee
141
141
142 #########################################################
142 #########################################################
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
143 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
144 #########################################################
144 #########################################################
145 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
145 sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db
146 sqlalchemy.db1.echo = True
146 sqlalchemy.db1.echo = false
147 sqlalchemy.db1.pool_recycle = 3600
147 sqlalchemy.db1.pool_recycle = 3600
148 sqlalchemy.convert_unicode = true
148 sqlalchemy.convert_unicode = true
149
149
150 ################################
150 ################################
151 ### LOGGING CONFIGURATION ####
151 ### LOGGING CONFIGURATION ####
152 ################################
152 ################################
153 [loggers]
153 [loggers]
154 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
154 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
155
155
156 [handlers]
156 [handlers]
157 keys = console, console_sql
157 keys = console, console_sql
158
158
159 [formatters]
159 [formatters]
160 keys = generic, color_formatter, color_formatter_sql
160 keys = generic, color_formatter, color_formatter_sql
161
161
162 #############
162 #############
163 ## LOGGERS ##
163 ## LOGGERS ##
164 #############
164 #############
165 [logger_root]
165 [logger_root]
166 level = NOTSET
166 level = NOTSET
167 handlers = console
167 handlers = console
168
168
169 [logger_routes]
169 [logger_routes]
170 level = DEBUG
170 level = DEBUG
171 handlers =
171 handlers =
172 qualname = routes.middleware
172 qualname = routes.middleware
173 # "level = DEBUG" logs the route matched and routing variables.
173 # "level = DEBUG" logs the route matched and routing variables.
174 propagate = 1
174 propagate = 1
175
175
176 [logger_beaker]
176 [logger_beaker]
177 level = DEBUG
177 level = DEBUG
178 handlers =
178 handlers =
179 qualname = beaker.container
179 qualname = beaker.container
180 propagate = 1
180 propagate = 1
181
181
182 [logger_templates]
182 [logger_templates]
183 level = INFO
183 level = INFO
184 handlers =
184 handlers =
185 qualname = pylons.templating
185 qualname = pylons.templating
186 propagate = 1
186 propagate = 1
187
187
188 [logger_rhodecode]
188 [logger_rhodecode]
189 level = DEBUG
189 level = DEBUG
190 handlers =
190 handlers =
191 qualname = rhodecode
191 qualname = rhodecode
192 propagate = 1
192 propagate = 1
193
193
194 [logger_sqlalchemy]
194 [logger_sqlalchemy]
195 level = INFO
195 level = INFO
196 handlers = console_sql
196 handlers = console_sql
197 qualname = sqlalchemy.engine
197 qualname = sqlalchemy.engine
198 propagate = 0
198 propagate = 0
199
199
200 ##############
200 ##############
201 ## HANDLERS ##
201 ## HANDLERS ##
202 ##############
202 ##############
203
203
204 [handler_console]
204 [handler_console]
205 class = StreamHandler
205 class = StreamHandler
206 args = (sys.stderr,)
206 args = (sys.stderr,)
207 level = INFO
207 level = INFO
208 formatter = color_formatter
208 formatter = color_formatter
209
209
210 [handler_console_sql]
210 [handler_console_sql]
211 class = StreamHandler
211 class = StreamHandler
212 args = (sys.stderr,)
212 args = (sys.stderr,)
213 level = WARN
213 level = WARN
214 formatter = color_formatter_sql
214 formatter = color_formatter_sql
215
215
216 ################
216 ################
217 ## FORMATTERS ##
217 ## FORMATTERS ##
218 ################
218 ################
219
219
220 [formatter_generic]
220 [formatter_generic]
221 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
221 format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
222 datefmt = %Y-%m-%d %H:%M:%S
222 datefmt = %Y-%m-%d %H:%M:%S
223
223
224 [formatter_color_formatter]
224 [formatter_color_formatter]
225 class=rhodecode.lib.colored_formatter.ColorFormatter
225 class=rhodecode.lib.colored_formatter.ColorFormatter
226 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
226 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
227 datefmt = %Y-%m-%d %H:%M:%S
227 datefmt = %Y-%m-%d %H:%M:%S
228
228
229 [formatter_color_formatter_sql]
229 [formatter_color_formatter_sql]
230 class=rhodecode.lib.colored_formatter.ColorFormatterSql
230 class=rhodecode.lib.colored_formatter.ColorFormatterSql
231 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
231 format= %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s
232 datefmt = %Y-%m-%d %H:%M:%S No newline at end of file
232 datefmt = %Y-%m-%d %H:%M:%S
@@ -1,85 +1,80 b''
1 """Pylons environment configuration"""
1 """Pylons environment configuration"""
2
2
3 import os
3 import os
4 import logging
4 import logging
5
5
6 from mako.lookup import TemplateLookup
6 from mako.lookup import TemplateLookup
7 from pylons.configuration import PylonsConfig
7 from pylons.configuration import PylonsConfig
8 from pylons.error import handle_mako_error
8 from pylons.error import handle_mako_error
9
9
10 import rhodecode.lib.app_globals as app_globals
10 import rhodecode.lib.app_globals as app_globals
11 import rhodecode.lib.helpers
11 import rhodecode.lib.helpers
12
12
13 from rhodecode.config.routing import make_map
13 from rhodecode.config.routing import make_map
14 from rhodecode.lib import celerypylons
14 from rhodecode.lib import celerypylons
15 from rhodecode.lib import engine_from_config
15 from rhodecode.lib import engine_from_config
16 from rhodecode.lib.timerproxy import TimerProxy
16 from rhodecode.lib.timerproxy import TimerProxy
17 from rhodecode.lib.auth import set_available_permissions
17 from rhodecode.lib.auth import set_available_permissions
18 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
18 from rhodecode.lib.utils import repo2db_mapper, make_ui, set_rhodecode_config
19 from rhodecode.model import init_model
19 from rhodecode.model import init_model
20 from rhodecode.model.scm import ScmModel
20 from rhodecode.model.scm import ScmModel
21
21
22 log = logging.getLogger(__name__)
22 log = logging.getLogger(__name__)
23
23
24
24
25 def load_environment(global_conf, app_conf, initial=False):
25 def load_environment(global_conf, app_conf, initial=False):
26 """Configure the Pylons environment via the ``pylons.config``
26 """Configure the Pylons environment via the ``pylons.config``
27 object
27 object
28 """
28 """
29 config = PylonsConfig()
29 config = PylonsConfig()
30
30
31 # Pylons paths
31 # Pylons paths
32 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
32 root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33 paths = dict(root=root,
33 paths = dict(root=root,
34 controllers=os.path.join(root, 'controllers'),
34 controllers=os.path.join(root, 'controllers'),
35 static_files=os.path.join(root, 'public'),
35 static_files=os.path.join(root, 'public'),
36 templates=[os.path.join(root, 'templates')])
36 templates=[os.path.join(root, 'templates')])
37
37
38 # Initialize config with the basic options
38 # Initialize config with the basic options
39 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
39 config.init_app(global_conf, app_conf, package='rhodecode', paths=paths)
40
40
41 config['routes.map'] = make_map(config)
41 config['routes.map'] = make_map(config)
42 config['pylons.app_globals'] = app_globals.Globals(config)
42 config['pylons.app_globals'] = app_globals.Globals(config)
43 config['pylons.h'] = rhodecode.lib.helpers
43 config['pylons.h'] = rhodecode.lib.helpers
44
44
45 # Setup cache object as early as possible
45 # Setup cache object as early as possible
46 import pylons
46 import pylons
47 pylons.cache._push_object(config['pylons.app_globals'].cache)
47 pylons.cache._push_object(config['pylons.app_globals'].cache)
48
48
49 # Create the Mako TemplateLookup, with the default auto-escaping
49 # Create the Mako TemplateLookup, with the default auto-escaping
50 config['pylons.app_globals'].mako_lookup = TemplateLookup(
50 config['pylons.app_globals'].mako_lookup = TemplateLookup(
51 directories=paths['templates'],
51 directories=paths['templates'],
52 error_handler=handle_mako_error,
52 error_handler=handle_mako_error,
53 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
53 module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
54 input_encoding='utf-8', default_filters=['escape'],
54 input_encoding='utf-8', default_filters=['escape'],
55 imports=['from webhelpers.html import escape'])
55 imports=['from webhelpers.html import escape'])
56
56
57 #sets the c attribute access when don't existing attribute are accessed
57 #sets the c attribute access when don't existing attribute are accessed
58 config['pylons.strict_tmpl_context'] = True
58 config['pylons.strict_tmpl_context'] = True
59 test = os.path.split(config['__file__'])[-1] == 'test.ini'
59 test = os.path.split(config['__file__'])[-1] == 'test.ini'
60 if test:
60 if test:
61 from rhodecode.lib.utils import create_test_env, create_test_index
61 from rhodecode.lib.utils import create_test_env, create_test_index
62 from rhodecode.tests import TESTS_TMP_PATH
62 from rhodecode.tests import TESTS_TMP_PATH
63 create_test_env(TESTS_TMP_PATH, config)
63 create_test_env(TESTS_TMP_PATH, config)
64 create_test_index(TESTS_TMP_PATH, True)
64 create_test_index(TESTS_TMP_PATH, True)
65
65
66 #MULTIPLE DB configs
66 #MULTIPLE DB configs
67 # Setup the SQLAlchemy database engine
67 # Setup the SQLAlchemy database engine
68 if config['debug'] and not test:
68 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
69 #use query time debugging.
70 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.',
71 proxy=TimerProxy())
72 else:
73 sa_engine_db1 = engine_from_config(config, 'sqlalchemy.db1.')
74
69
75 init_model(sa_engine_db1)
70 init_model(sa_engine_db1)
76
71
77 repos_path = make_ui('db').configitems('paths')[0][1]
72 repos_path = make_ui('db').configitems('paths')[0][1]
78 repo2db_mapper(ScmModel().repo_scan(repos_path))
73 repo2db_mapper(ScmModel().repo_scan(repos_path))
79 set_available_permissions(config)
74 set_available_permissions(config)
80 config['base_path'] = repos_path
75 config['base_path'] = repos_path
81 set_rhodecode_config(config)
76 set_rhodecode_config(config)
82 # CONFIGURATION OPTIONS HERE (note: all config options will override
77 # CONFIGURATION OPTIONS HERE (note: all config options will override
83 # any Pylons config options)
78 # any Pylons config options)
84
79
85 return config
80 return config
@@ -1,244 +1,286 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.lib.__init__
3 rhodecode.lib.__init__
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Some simple helper functions
6 Some simple helper functions
7
7
8 :created_on: Jan 5, 2011
8 :created_on: Jan 5, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26
26
27 def __get_lem():
27 def __get_lem():
28 from pygments import lexers
28 from pygments import lexers
29 from string import lower
29 from string import lower
30 from collections import defaultdict
30 from collections import defaultdict
31
31
32 d = defaultdict(lambda: [])
32 d = defaultdict(lambda: [])
33
33
34 def __clean(s):
34 def __clean(s):
35 s = s.lstrip('*')
35 s = s.lstrip('*')
36 s = s.lstrip('.')
36 s = s.lstrip('.')
37
37
38 if s.find('[') != -1:
38 if s.find('[') != -1:
39 exts = []
39 exts = []
40 start, stop = s.find('['), s.find(']')
40 start, stop = s.find('['), s.find(']')
41
41
42 for suffix in s[start + 1:stop]:
42 for suffix in s[start + 1:stop]:
43 exts.append(s[:s.find('[')] + suffix)
43 exts.append(s[:s.find('[')] + suffix)
44 return map(lower, exts)
44 return map(lower, exts)
45 else:
45 else:
46 return map(lower, [s])
46 return map(lower, [s])
47
47
48 for lx, t in sorted(lexers.LEXERS.items()):
48 for lx, t in sorted(lexers.LEXERS.items()):
49 m = map(__clean, t[-2])
49 m = map(__clean, t[-2])
50 if m:
50 if m:
51 m = reduce(lambda x, y: x + y, m)
51 m = reduce(lambda x, y: x + y, m)
52 for ext in m:
52 for ext in m:
53 desc = lx.replace('Lexer', '')
53 desc = lx.replace('Lexer', '')
54 d[ext].append(desc)
54 d[ext].append(desc)
55
55
56 return dict(d)
56 return dict(d)
57
57
58 # language map is also used by whoosh indexer, which for those specified
58 # language map is also used by whoosh indexer, which for those specified
59 # extensions will index it's content
59 # extensions will index it's content
60 LANGUAGES_EXTENSIONS_MAP = __get_lem()
60 LANGUAGES_EXTENSIONS_MAP = __get_lem()
61
61
62 # Additional mappings that are not present in the pygments lexers
62 # Additional mappings that are not present in the pygments lexers
63 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
63 # NOTE: that this will overide any mappings in LANGUAGES_EXTENSIONS_MAP
64 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}
64 ADDITIONAL_MAPPINGS = {'xaml': 'XAML'}
65
65
66 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
66 LANGUAGES_EXTENSIONS_MAP.update(ADDITIONAL_MAPPINGS)
67
67
68
68
69 def str2bool(_str):
69 def str2bool(_str):
70 """
70 """
71 returs True/False value from given string, it tries to translate the
71 returs True/False value from given string, it tries to translate the
72 string into boolean
72 string into boolean
73
73
74 :param _str: string value to translate into boolean
74 :param _str: string value to translate into boolean
75 :rtype: boolean
75 :rtype: boolean
76 :returns: boolean from given string
76 :returns: boolean from given string
77 """
77 """
78 if _str is None:
78 if _str is None:
79 return False
79 return False
80 if _str in (True, False):
80 if _str in (True, False):
81 return _str
81 return _str
82 _str = str(_str).strip().lower()
82 _str = str(_str).strip().lower()
83 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
83 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
84
84
85
85
86 def convert_line_endings(temp, mode):
86 def convert_line_endings(temp, mode):
87 from string import replace
87 from string import replace
88 #modes: 0 - Unix, 1 - Mac, 2 - DOS
88 #modes: 0 - Unix, 1 - Mac, 2 - DOS
89 if mode == 0:
89 if mode == 0:
90 temp = replace(temp, '\r\n', '\n')
90 temp = replace(temp, '\r\n', '\n')
91 temp = replace(temp, '\r', '\n')
91 temp = replace(temp, '\r', '\n')
92 elif mode == 1:
92 elif mode == 1:
93 temp = replace(temp, '\r\n', '\r')
93 temp = replace(temp, '\r\n', '\r')
94 temp = replace(temp, '\n', '\r')
94 temp = replace(temp, '\n', '\r')
95 elif mode == 2:
95 elif mode == 2:
96 import re
96 import re
97 temp = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", temp)
97 temp = re.sub("\r(?!\n)|(?<!\r)\n", "\r\n", temp)
98 return temp
98 return temp
99
99
100
100
101 def detect_mode(line, default):
101 def detect_mode(line, default):
102 """
102 """
103 Detects line break for given line, if line break couldn't be found
103 Detects line break for given line, if line break couldn't be found
104 given default value is returned
104 given default value is returned
105
105
106 :param line: str line
106 :param line: str line
107 :param default: default
107 :param default: default
108 :rtype: int
108 :rtype: int
109 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
109 :return: value of line end on of 0 - Unix, 1 - Mac, 2 - DOS
110 """
110 """
111 if line.endswith('\r\n'):
111 if line.endswith('\r\n'):
112 return 2
112 return 2
113 elif line.endswith('\n'):
113 elif line.endswith('\n'):
114 return 0
114 return 0
115 elif line.endswith('\r'):
115 elif line.endswith('\r'):
116 return 1
116 return 1
117 else:
117 else:
118 return default
118 return default
119
119
120
120
121 def generate_api_key(username, salt=None):
121 def generate_api_key(username, salt=None):
122 """
122 """
123 Generates unique API key for given username,if salt is not given
123 Generates unique API key for given username,if salt is not given
124 it'll be generated from some random string
124 it'll be generated from some random string
125
125
126 :param username: username as string
126 :param username: username as string
127 :param salt: salt to hash generate KEY
127 :param salt: salt to hash generate KEY
128 :rtype: str
128 :rtype: str
129 :returns: sha1 hash from username+salt
129 :returns: sha1 hash from username+salt
130 """
130 """
131 from tempfile import _RandomNameSequence
131 from tempfile import _RandomNameSequence
132 import hashlib
132 import hashlib
133
133
134 if salt is None:
134 if salt is None:
135 salt = _RandomNameSequence().next()
135 salt = _RandomNameSequence().next()
136
136
137 return hashlib.sha1(username + salt).hexdigest()
137 return hashlib.sha1(username + salt).hexdigest()
138
138
139
139
140 def safe_unicode(_str, from_encoding='utf8'):
140 def safe_unicode(_str, from_encoding='utf8'):
141 """
141 """
142 safe unicode function. In case of UnicodeDecode error we try to return
142 safe unicode function. In case of UnicodeDecode error we try to return
143 unicode with errors replace
143 unicode with errors replace
144
144
145 :param _str: string to decode
145 :param _str: string to decode
146 :rtype: unicode
146 :rtype: unicode
147 :returns: unicode object
147 :returns: unicode object
148 """
148 """
149
149
150 if isinstance(_str, unicode):
150 if isinstance(_str, unicode):
151 return _str
151 return _str
152
152
153 try:
153 try:
154 u_str = unicode(_str, from_encoding)
154 u_str = unicode(_str, from_encoding)
155 except UnicodeDecodeError:
155 except UnicodeDecodeError:
156 u_str = unicode(_str, from_encoding, 'replace')
156 u_str = unicode(_str, from_encoding, 'replace')
157
157
158 return u_str
158 return u_str
159
159
160
160
161 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
161 def engine_from_config(configuration, prefix='sqlalchemy.', **kwargs):
162 """
162 """
163 Custom engine_from_config functions that makes sure we use NullPool for
163 Custom engine_from_config functions that makes sure we use NullPool for
164 file based sqlite databases. This prevents errors on sqlite.
164 file based sqlite databases. This prevents errors on sqlite. This only
165 applies to sqlalchemy versions < 0.7.0
165
166
166 """
167 """
168 import sqlalchemy
167 from sqlalchemy import engine_from_config as efc
169 from sqlalchemy import engine_from_config as efc
168 from sqlalchemy.pool import NullPool
170 import logging
171
172 if int(sqlalchemy.__version__.split('.')[1]) < 7:
173
174 # This solution should work for sqlalchemy < 0.7.0, and should use
175 # proxy=TimerProxy() for execution time profiling
176
177 from sqlalchemy.pool import NullPool
178 url = configuration[prefix + 'url']
169
179
170 url = configuration[prefix + 'url']
180 if url.startswith('sqlite'):
181 kwargs.update({'poolclass': NullPool})
182 return efc(configuration, prefix, **kwargs)
183 else:
184 import time
185 from sqlalchemy import event
186 from sqlalchemy.engine import Engine
187
188 log = logging.getLogger('timerproxy')
189 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
190 engine = efc(configuration, prefix, **kwargs)
171
191
172 if url.startswith('sqlite'):
192 def color_sql(sql):
173 kwargs.update({'poolclass': NullPool})
193 COLOR_SEQ = "\033[1;%dm"
194 COLOR_SQL = YELLOW
195 normal = '\x1b[0m'
196 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
197
198 if configuration['debug']:
199 #attach events only for debug configuration
174
200
175 return efc(configuration, prefix, **kwargs)
201 def before_cursor_execute(conn, cursor, statement,
202 parameters, context, executemany):
203 context._query_start_time = time.time()
204 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
205
206
207 def after_cursor_execute(conn, cursor, statement,
208 parameters, context, executemany):
209 total = time.time() - context._query_start_time
210 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
211
212 event.listen(engine, "before_cursor_execute",
213 before_cursor_execute)
214 event.listen(engine, "after_cursor_execute",
215 after_cursor_execute)
216
217 return engine
176
218
177
219
178 def age(curdate):
220 def age(curdate):
179 """
221 """
180 turns a datetime into an age string.
222 turns a datetime into an age string.
181
223
182 :param curdate: datetime object
224 :param curdate: datetime object
183 :rtype: unicode
225 :rtype: unicode
184 :returns: unicode words describing age
226 :returns: unicode words describing age
185 """
227 """
186
228
187 from datetime import datetime
229 from datetime import datetime
188 from webhelpers.date import time_ago_in_words
230 from webhelpers.date import time_ago_in_words
189
231
190 _ = lambda s:s
232 _ = lambda s:s
191
233
192 if not curdate:
234 if not curdate:
193 return ''
235 return ''
194
236
195 agescales = [(_(u"year"), 3600 * 24 * 365),
237 agescales = [(_(u"year"), 3600 * 24 * 365),
196 (_(u"month"), 3600 * 24 * 30),
238 (_(u"month"), 3600 * 24 * 30),
197 (_(u"day"), 3600 * 24),
239 (_(u"day"), 3600 * 24),
198 (_(u"hour"), 3600),
240 (_(u"hour"), 3600),
199 (_(u"minute"), 60),
241 (_(u"minute"), 60),
200 (_(u"second"), 1), ]
242 (_(u"second"), 1), ]
201
243
202 age = datetime.now() - curdate
244 age = datetime.now() - curdate
203 age_seconds = (age.days * agescales[2][1]) + age.seconds
245 age_seconds = (age.days * agescales[2][1]) + age.seconds
204 pos = 1
246 pos = 1
205 for scale in agescales:
247 for scale in agescales:
206 if scale[1] <= age_seconds:
248 if scale[1] <= age_seconds:
207 if pos == 6:pos = 5
249 if pos == 6:pos = 5
208 return '%s %s' % (time_ago_in_words(curdate,
250 return '%s %s' % (time_ago_in_words(curdate,
209 agescales[pos][0]), _('ago'))
251 agescales[pos][0]), _('ago'))
210 pos += 1
252 pos += 1
211
253
212 return _(u'just now')
254 return _(u'just now')
213
255
214
256
215 def credentials_hidder(uri):
257 def credentials_hidder(uri):
216 """
258 """
217 Removes user:password from given url string
259 Removes user:password from given url string
218
260
219 :param uri:
261 :param uri:
220 :rtype: unicode
262 :rtype: unicode
221 :returns: filtered list of strings
263 :returns: filtered list of strings
222 """
264 """
223 if not uri:
265 if not uri:
224 return ''
266 return ''
225
267
226 proto = ''
268 proto = ''
227
269
228 for pat in ('https://', 'http://'):
270 for pat in ('https://', 'http://'):
229 if uri.startswith(pat):
271 if uri.startswith(pat):
230 uri = uri[len(pat):]
272 uri = uri[len(pat):]
231 proto = pat
273 proto = pat
232 break
274 break
233
275
234 # remove passwords and username
276 # remove passwords and username
235 uri = uri[uri.find('@') + 1:]
277 uri = uri[uri.find('@') + 1:]
236
278
237 # get the port
279 # get the port
238 cred_pos = uri.find(':')
280 cred_pos = uri.find(':')
239 if cred_pos == -1:
281 if cred_pos == -1:
240 host, port = uri, None
282 host, port = uri, None
241 else:
283 else:
242 host, port = uri[:cred_pos], uri[cred_pos + 1:]
284 host, port = uri[:cred_pos], uri[cred_pos + 1:]
243
285
244 return filter(None, [proto, host, port])
286 return filter(None, [proto, host, port])
@@ -1,85 +1,85 b''
1
1
2 import logging
2 import logging
3
3
4 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
4 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
5
5
6 # Sequences
6 # Sequences
7 RESET_SEQ = "\033[0m"
7 RESET_SEQ = "\033[0m"
8 COLOR_SEQ = "\033[1;%dm"
8 COLOR_SEQ = "\033[1;%dm"
9 BOLD_SEQ = "\033[1m"
9 BOLD_SEQ = "\033[1m"
10
10
11 COLORS = {
11 COLORS = {
12 'CRITICAL': MAGENTA,
12 'CRITICAL': MAGENTA,
13 'ERROR': RED,
13 'ERROR': RED,
14 'WARNING': CYAN,
14 'WARNING': CYAN,
15 'INFO': GREEN,
15 'INFO': GREEN,
16 'DEBUG': BLUE,
16 'DEBUG': BLUE,
17 'SQL': YELLOW
17 'SQL': YELLOW
18 }
18 }
19
19
20
20
21 def one_space_trim(s):
21 def one_space_trim(s):
22 if s.find(" ") == -1:
22 if s.find(" ") == -1:
23 return s
23 return s
24 else:
24 else:
25 s = s.replace(' ', ' ')
25 s = s.replace(' ', ' ')
26 return one_space_trim(s)
26 return one_space_trim(s)
27
27
28
28
29 def format_sql(sql):
29 def format_sql(sql):
30 sql = sql.replace('\n', '')
30 sql = sql.replace('\n', '')
31 sql = one_space_trim(sql)
31 sql = one_space_trim(sql)
32 sql = sql\
32 sql = sql\
33 .replace(',', ',\n\t')\
33 .replace(',', ',\n\t')\
34 .replace('SELECT', '\n\tSELECT \n\t')\
34 .replace('SELECT', '\n\tSELECT \n\t')\
35 .replace('UPDATE', '\n\tUPDATE \n\t')\
35 .replace('UPDATE', '\n\tUPDATE \n\t')\
36 .replace('DELETE', '\n\tDELETE \n\t')\
36 .replace('DELETE', '\n\tDELETE \n\t')\
37 .replace('FROM', '\n\tFROM')\
37 .replace('FROM', '\n\tFROM')\
38 .replace('ORDER BY', '\n\tORDER BY')\
38 .replace('ORDER BY', '\n\tORDER BY')\
39 .replace('LIMIT', '\n\tLIMIT')\
39 .replace('LIMIT', '\n\tLIMIT')\
40 .replace('WHERE', '\n\tWHERE')\
40 .replace('WHERE', '\n\tWHERE')\
41 .replace('AND', '\n\tAND')\
41 .replace('AND', '\n\tAND')\
42 .replace('LEFT', '\n\tLEFT')\
42 .replace('LEFT', '\n\tLEFT')\
43 .replace('INNER', '\n\tINNER')\
43 .replace('INNER', '\n\tINNER')\
44 .replace('INSERT', '\n\tINSERT')\
44 .replace('INSERT', '\n\tINSERT')\
45 .replace('DELETE', '\n\tDELETE')
45 .replace('DELETE', '\n\tDELETE')
46 return sql
46 return sql
47
47
48
48
49 class ColorFormatter(logging.Formatter):
49 class ColorFormatter(logging.Formatter):
50
50
51 def __init__(self, *args, **kwargs):
51 def __init__(self, *args, **kwargs):
52 # can't do super(...) here because Formatter is an old school class
52 # can't do super(...) here because Formatter is an old school class
53 logging.Formatter.__init__(self, *args, **kwargs)
53 logging.Formatter.__init__(self, *args, **kwargs)
54
54
55 def format(self, record):
55 def format(self, record):
56 """
56 """
57 Changes record's levelname to use with COLORS enum
57 Changes record's levelname to use with COLORS enum
58 """
58 """
59
59
60 levelname = record.levelname
60 levelname = record.levelname
61 start = COLOR_SEQ % (COLORS[levelname])
61 start = COLOR_SEQ % (COLORS[levelname])
62 def_record = logging.Formatter.format(self, record)
62 def_record = logging.Formatter.format(self, record)
63 end = RESET_SEQ
63 end = RESET_SEQ
64
64
65 colored_record = start + def_record + end
65 colored_record = ''.join([start, def_record, end])
66 return colored_record
66 return colored_record
67
67
68
68
69 class ColorFormatterSql(logging.Formatter):
69 class ColorFormatterSql(logging.Formatter):
70
70
71 def __init__(self, *args, **kwargs):
71 def __init__(self, *args, **kwargs):
72 # can't do super(...) here because Formatter is an old school class
72 # can't do super(...) here because Formatter is an old school class
73 logging.Formatter.__init__(self, *args, **kwargs)
73 logging.Formatter.__init__(self, *args, **kwargs)
74
74
75 def format(self, record):
75 def format(self, record):
76 """
76 """
77 Changes record's levelname to use with COLORS enum
77 Changes record's levelname to use with COLORS enum
78 """
78 """
79
79
80 start = COLOR_SEQ % (COLORS['SQL'])
80 start = COLOR_SEQ % (COLORS['SQL'])
81 def_record = format_sql(logging.Formatter.format(self, record))
81 def_record = format_sql(logging.Formatter.format(self, record))
82 end = RESET_SEQ
82 end = RESET_SEQ
83
83
84 colored_record = start + def_record + end
84 colored_record = ''.join([start, def_record, end])
85 return colored_record
85 return colored_record
@@ -1,30 +1,30 b''
1 from sqlalchemy.interfaces import ConnectionProxy
1 from sqlalchemy.interfaces import ConnectionProxy
2 import time
2 import time
3 import logging
3 import logging
4 log = logging.getLogger('timerproxy')
4 log = logging.getLogger('timerproxy')
5
5
6 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
6 BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38)
7
7
8
8
9 def color_sql(sql):
9 def color_sql(sql):
10 COLOR_SEQ = "\033[1;%dm"
10 COLOR_SEQ = "\033[1;%dm"
11 COLOR_SQL = YELLOW
11 COLOR_SQL = YELLOW
12 normal = '\x1b[0m'
12 normal = '\x1b[0m'
13 return COLOR_SEQ % COLOR_SQL + sql + normal
13 return ''.join([COLOR_SEQ % COLOR_SQL, sql, normal])
14
14
15
15
16 class TimerProxy(ConnectionProxy):
16 class TimerProxy(ConnectionProxy):
17
17
18 def __init__(self):
18 def __init__(self):
19 super(TimerProxy, self).__init__()
19 super(TimerProxy, self).__init__()
20
20
21 def cursor_execute(self, execute, cursor, statement, parameters,
21 def cursor_execute(self, execute, cursor, statement, parameters,
22 context, executemany):
22 context, executemany):
23
23
24 now = time.time()
24 now = time.time()
25 try:
25 try:
26 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
26 log.info(color_sql(">>>>> STARTING QUERY >>>>>"))
27 return execute(cursor, statement, parameters, context)
27 return execute(cursor, statement, parameters, context)
28 finally:
28 finally:
29 total = time.time() - now
29 total = time.time() - now
30 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
30 log.info(color_sql("<<<<< TOTAL TIME: %f <<<<<" % total))
@@ -1,566 +1,566 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.db
3 rhodecode.model.db
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Database Models for RhodeCode
6 Database Models for RhodeCode
7
7
8 :created_on: Apr 08, 2010
8 :created_on: Apr 08, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import logging
27 import logging
28 import datetime
28 import datetime
29 from datetime import date
29 from datetime import date
30
30
31 from sqlalchemy import *
31 from sqlalchemy import *
32 from sqlalchemy.exc import DatabaseError
32 from sqlalchemy.exc import DatabaseError
33 from sqlalchemy.orm import relationship, backref
33 from sqlalchemy.orm import relationship, backref
34 from sqlalchemy.orm.interfaces import MapperExtension
34 from sqlalchemy.orm.interfaces import MapperExtension
35
35
36 from rhodecode.lib import str2bool
36 from rhodecode.lib import str2bool
37 from rhodecode.model.meta import Base, Session
37 from rhodecode.model.meta import Base, Session
38 from rhodecode.model.caching_query import FromCache
38 from rhodecode.model.caching_query import FromCache
39
39
40 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
41
41
42 #==============================================================================
42 #==============================================================================
43 # MAPPER EXTENSIONS
43 # MAPPER EXTENSIONS
44 #==============================================================================
44 #==============================================================================
45
45
46 class RepositoryMapper(MapperExtension):
46 class RepositoryMapper(MapperExtension):
47 def after_update(self, mapper, connection, instance):
47 def after_update(self, mapper, connection, instance):
48 pass
48 pass
49
49
50
50
51 class RhodeCodeSettings(Base):
51 class RhodeCodeSettings(Base):
52 __tablename__ = 'rhodecode_settings'
52 __tablename__ = 'rhodecode_settings'
53 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
53 __table_args__ = (UniqueConstraint('app_settings_name'), {'extend_existing':True})
54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
57
57
58 def __init__(self, k='', v=''):
58 def __init__(self, k='', v=''):
59 self.app_settings_name = k
59 self.app_settings_name = k
60 self.app_settings_value = v
60 self.app_settings_value = v
61
61
62 def __repr__(self):
62 def __repr__(self):
63 return "<%s('%s:%s')>" % (self.__class__.__name__,
63 return "<%s('%s:%s')>" % (self.__class__.__name__,
64 self.app_settings_name, self.app_settings_value)
64 self.app_settings_name, self.app_settings_value)
65
65
66
66
67 @classmethod
67 @classmethod
68 def get_by_name(cls, ldap_key):
68 def get_by_name(cls, ldap_key):
69 return Session.query(cls)\
69 return Session.query(cls)\
70 .filter(cls.app_settings_name == ldap_key).scalar()
70 .filter(cls.app_settings_name == ldap_key).scalar()
71
71
72 @classmethod
72 @classmethod
73 def get_app_settings(cls, cache=False):
73 def get_app_settings(cls, cache=False):
74
74
75 ret = Session.query(cls)
75 ret = Session.query(cls)
76
76
77 if cache:
77 if cache:
78 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
78 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
79
79
80 if not ret:
80 if not ret:
81 raise Exception('Could not get application settings !')
81 raise Exception('Could not get application settings !')
82 settings = {}
82 settings = {}
83 for each in ret:
83 for each in ret:
84 settings['rhodecode_' + each.app_settings_name] = \
84 settings['rhodecode_' + each.app_settings_name] = \
85 each.app_settings_value
85 each.app_settings_value
86
86
87 return settings
87 return settings
88
88
89 @classmethod
89 @classmethod
90 def get_ldap_settings(cls, cache=False):
90 def get_ldap_settings(cls, cache=False):
91 ret = Session.query(cls)\
91 ret = Session.query(cls)\
92 .filter(cls.app_settings_name.startswith('ldap_'))\
92 .filter(cls.app_settings_name.startswith('ldap_'))\
93 .all()
93 .all()
94 fd = {}
94 fd = {}
95 for row in ret:
95 for row in ret:
96 fd.update({row.app_settings_name:row.app_settings_value})
96 fd.update({row.app_settings_name:row.app_settings_value})
97 return fd
97 return fd
98
98
99
99
100 class RhodeCodeUi(Base):
100 class RhodeCodeUi(Base):
101 __tablename__ = 'rhodecode_ui'
101 __tablename__ = 'rhodecode_ui'
102 __table_args__ = {'useexisting':True}
102 __table_args__ = {'extend_existing':True}
103 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
103 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
104 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
104 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
105 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
105 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
106 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
106 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
107 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
107 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
108
108
109
109
110 @classmethod
110 @classmethod
111 def get_by_key(cls, key):
111 def get_by_key(cls, key):
112 return Session.query(cls).filter(cls.ui_key == key)
112 return Session.query(cls).filter(cls.ui_key == key)
113
113
114
114
115 class User(Base):
115 class User(Base):
116 __tablename__ = 'users'
116 __tablename__ = 'users'
117 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
117 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':True})
118 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
118 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
119 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
119 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
120 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
120 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
121 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
121 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
122 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
122 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
123 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
123 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
124 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
124 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
125 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
125 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
126 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
126 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
127 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
127 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
128 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
128 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
129
129
130 user_log = relationship('UserLog', cascade='all')
130 user_log = relationship('UserLog', cascade='all')
131 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
131 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
132
132
133 repositories = relationship('Repository')
133 repositories = relationship('Repository')
134 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
134 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
135 repo_to_perm = relationship('RepoToPerm', primaryjoin='RepoToPerm.user_id==User.user_id', cascade='all')
135 repo_to_perm = relationship('RepoToPerm', primaryjoin='RepoToPerm.user_id==User.user_id', cascade='all')
136
136
137 group_member = relationship('UsersGroupMember', cascade='all')
137 group_member = relationship('UsersGroupMember', cascade='all')
138
138
139 @property
139 @property
140 def full_contact(self):
140 def full_contact(self):
141 return '%s %s <%s>' % (self.name, self.lastname, self.email)
141 return '%s %s <%s>' % (self.name, self.lastname, self.email)
142
142
143 @property
143 @property
144 def short_contact(self):
144 def short_contact(self):
145 return '%s %s' % (self.name, self.lastname)
145 return '%s %s' % (self.name, self.lastname)
146
146
147
147
148 @property
148 @property
149 def is_admin(self):
149 def is_admin(self):
150 return self.admin
150 return self.admin
151
151
152 def __repr__(self):
152 def __repr__(self):
153 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
153 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
154 self.user_id, self.username)
154 self.user_id, self.username)
155
155
156 @classmethod
156 @classmethod
157 def by_username(cls, username):
157 def by_username(cls, username):
158 return Session.query(cls).filter(cls.username == username).one()
158 return Session.query(cls).filter(cls.username == username).one()
159
159
160
160
161 def update_lastlogin(self):
161 def update_lastlogin(self):
162 """Update user lastlogin"""
162 """Update user lastlogin"""
163
163
164 try:
164 try:
165 session = Session.object_session(self)
165 session = Session.object_session(self)
166 self.last_login = datetime.datetime.now()
166 self.last_login = datetime.datetime.now()
167 session.add(self)
167 session.add(self)
168 session.commit()
168 session.commit()
169 log.debug('updated user %s lastlogin', self.username)
169 log.debug('updated user %s lastlogin', self.username)
170 except (DatabaseError,):
170 except (DatabaseError,):
171 session.rollback()
171 session.rollback()
172
172
173
173
174 class UserLog(Base):
174 class UserLog(Base):
175 __tablename__ = 'user_logs'
175 __tablename__ = 'user_logs'
176 __table_args__ = {'useexisting':True}
176 __table_args__ = {'extend_existing':True}
177 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
177 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
178 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
178 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
179 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
179 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
180 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
180 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
181 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
181 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
182 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
182 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
183 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
183 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
184
184
185 @property
185 @property
186 def action_as_day(self):
186 def action_as_day(self):
187 return date(*self.action_date.timetuple()[:3])
187 return date(*self.action_date.timetuple()[:3])
188
188
189 user = relationship('User')
189 user = relationship('User')
190 repository = relationship('Repository')
190 repository = relationship('Repository')
191
191
192
192
193 class UsersGroup(Base):
193 class UsersGroup(Base):
194 __tablename__ = 'users_groups'
194 __tablename__ = 'users_groups'
195 __table_args__ = {'useexisting':True}
195 __table_args__ = {'extend_existing':True}
196
196
197 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
197 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
198 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
198 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
199 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
199 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
200
200
201 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
201 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
202
202
203
203
204 @classmethod
204 @classmethod
205 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
205 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
206 if case_insensitive:
206 if case_insensitive:
207 gr = Session.query(cls)\
207 gr = Session.query(cls)\
208 .filter(cls.users_group_name.ilike(group_name))
208 .filter(cls.users_group_name.ilike(group_name))
209 else:
209 else:
210 gr = Session.query(UsersGroup)\
210 gr = Session.query(UsersGroup)\
211 .filter(UsersGroup.users_group_name == group_name)
211 .filter(UsersGroup.users_group_name == group_name)
212 if cache:
212 if cache:
213 gr = gr.options(FromCache("sql_cache_short",
213 gr = gr.options(FromCache("sql_cache_short",
214 "get_user_%s" % group_name))
214 "get_user_%s" % group_name))
215 return gr.scalar()
215 return gr.scalar()
216
216
217 class UsersGroupMember(Base):
217 class UsersGroupMember(Base):
218 __tablename__ = 'users_groups_members'
218 __tablename__ = 'users_groups_members'
219 __table_args__ = {'useexisting':True}
219 __table_args__ = {'extend_existing':True}
220
220
221 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
221 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
222 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
222 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
223 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
223 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
224
224
225 user = relationship('User', lazy='joined')
225 user = relationship('User', lazy='joined')
226 users_group = relationship('UsersGroup')
226 users_group = relationship('UsersGroup')
227
227
228 def __init__(self, gr_id='', u_id=''):
228 def __init__(self, gr_id='', u_id=''):
229 self.users_group_id = gr_id
229 self.users_group_id = gr_id
230 self.user_id = u_id
230 self.user_id = u_id
231
231
232 class Repository(Base):
232 class Repository(Base):
233 __tablename__ = 'repositories'
233 __tablename__ = 'repositories'
234 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
234 __table_args__ = (UniqueConstraint('repo_name'), {'extend_existing':True},)
235 __mapper_args__ = {'extension':RepositoryMapper()}
235 __mapper_args__ = {'extension':RepositoryMapper()}
236
236
237 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
237 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
238 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
238 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
239 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
239 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
240 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
240 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
241 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
241 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
242 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
242 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
243 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
243 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
244 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
244 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
245 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
245 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
246 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
246 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
247
247
248 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
248 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
249 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
249 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
250
250
251
251
252 user = relationship('User')
252 user = relationship('User')
253 fork = relationship('Repository', remote_side=repo_id)
253 fork = relationship('Repository', remote_side=repo_id)
254 group = relationship('Group')
254 group = relationship('Group')
255 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
255 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
256 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
256 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
257 stats = relationship('Statistics', cascade='all', uselist=False)
257 stats = relationship('Statistics', cascade='all', uselist=False)
258
258
259 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
259 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
260
260
261 logs = relationship('UserLog', cascade='all')
261 logs = relationship('UserLog', cascade='all')
262
262
263 def __repr__(self):
263 def __repr__(self):
264 return "<%s('%s:%s')>" % (self.__class__.__name__,
264 return "<%s('%s:%s')>" % (self.__class__.__name__,
265 self.repo_id, self.repo_name)
265 self.repo_id, self.repo_name)
266
266
267 @classmethod
267 @classmethod
268 def by_repo_name(cls, repo_name):
268 def by_repo_name(cls, repo_name):
269 return Session.query(cls).filter(cls.repo_name == repo_name).one()
269 return Session.query(cls).filter(cls.repo_name == repo_name).one()
270
270
271
271
272 @classmethod
272 @classmethod
273 def get_repo_forks(cls, repo_id):
273 def get_repo_forks(cls, repo_id):
274 return Session.query(cls).filter(Repository.fork_id == repo_id)
274 return Session.query(cls).filter(Repository.fork_id == repo_id)
275
275
276 @property
276 @property
277 def just_name(self):
277 def just_name(self):
278 return self.repo_name.split(os.sep)[-1]
278 return self.repo_name.split(os.sep)[-1]
279
279
280 @property
280 @property
281 def groups_with_parents(self):
281 def groups_with_parents(self):
282 groups = []
282 groups = []
283 if self.group is None:
283 if self.group is None:
284 return groups
284 return groups
285
285
286 cur_gr = self.group
286 cur_gr = self.group
287 groups.insert(0, cur_gr)
287 groups.insert(0, cur_gr)
288 while 1:
288 while 1:
289 gr = getattr(cur_gr, 'parent_group', None)
289 gr = getattr(cur_gr, 'parent_group', None)
290 cur_gr = cur_gr.parent_group
290 cur_gr = cur_gr.parent_group
291 if gr is None:
291 if gr is None:
292 break
292 break
293 groups.insert(0, gr)
293 groups.insert(0, gr)
294
294
295 return groups
295 return groups
296
296
297 @property
297 @property
298 def groups_and_repo(self):
298 def groups_and_repo(self):
299 return self.groups_with_parents, self.just_name
299 return self.groups_with_parents, self.just_name
300
300
301
301
302 class Group(Base):
302 class Group(Base):
303 __tablename__ = 'groups'
303 __tablename__ = 'groups'
304 __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'),
304 __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'),
305 CheckConstraint('group_id != group_parent_id'), {'useexisting':True},)
305 CheckConstraint('group_id != group_parent_id'), {'extend_existing':True},)
306 __mapper_args__ = {'order_by':'group_name'}
306 __mapper_args__ = {'order_by':'group_name'}
307
307
308 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
308 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
309 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
309 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
310 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
310 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
311 group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
311 group_description = Column("group_description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
312
312
313 parent_group = relationship('Group', remote_side=group_id)
313 parent_group = relationship('Group', remote_side=group_id)
314
314
315
315
316 def __init__(self, group_name='', parent_group=None):
316 def __init__(self, group_name='', parent_group=None):
317 self.group_name = group_name
317 self.group_name = group_name
318 self.parent_group = parent_group
318 self.parent_group = parent_group
319
319
320 def __repr__(self):
320 def __repr__(self):
321 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
321 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
322 self.group_name)
322 self.group_name)
323
323
324 @classmethod
324 @classmethod
325 def url_sep(cls):
325 def url_sep(cls):
326 return '/'
326 return '/'
327
327
328 @property
328 @property
329 def parents(self):
329 def parents(self):
330 parents_limit = 5
330 parents_limit = 5
331 groups = []
331 groups = []
332 if self.parent_group is None:
332 if self.parent_group is None:
333 return groups
333 return groups
334 cur_gr = self.parent_group
334 cur_gr = self.parent_group
335 groups.insert(0, cur_gr)
335 groups.insert(0, cur_gr)
336 cnt = 0
336 cnt = 0
337 while 1:
337 while 1:
338 cnt += 1
338 cnt += 1
339 gr = getattr(cur_gr, 'parent_group', None)
339 gr = getattr(cur_gr, 'parent_group', None)
340 cur_gr = cur_gr.parent_group
340 cur_gr = cur_gr.parent_group
341 if gr is None:
341 if gr is None:
342 break
342 break
343 if cnt == parents_limit:
343 if cnt == parents_limit:
344 # this will prevent accidental infinit loops
344 # this will prevent accidental infinit loops
345 log.error('group nested more than %s' %
345 log.error('group nested more than %s' %
346 parents_limit)
346 parents_limit)
347 break
347 break
348
348
349 groups.insert(0, gr)
349 groups.insert(0, gr)
350 return groups
350 return groups
351
351
352
352
353 @property
353 @property
354 def full_path(self):
354 def full_path(self):
355 return Group.url_sep().join([g.group_name for g in self.parents] +
355 return Group.url_sep().join([g.group_name for g in self.parents] +
356 [self.group_name])
356 [self.group_name])
357
357
358 @property
358 @property
359 def repositories(self):
359 def repositories(self):
360 return Session.query(Repository).filter(Repository.group == self)
360 return Session.query(Repository).filter(Repository.group == self)
361
361
362 class Permission(Base):
362 class Permission(Base):
363 __tablename__ = 'permissions'
363 __tablename__ = 'permissions'
364 __table_args__ = {'useexisting':True}
364 __table_args__ = {'extend_existing':True}
365 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
365 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
366 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
366 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
367 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
367 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
368
368
369 def __repr__(self):
369 def __repr__(self):
370 return "<%s('%s:%s')>" % (self.__class__.__name__,
370 return "<%s('%s:%s')>" % (self.__class__.__name__,
371 self.permission_id, self.permission_name)
371 self.permission_id, self.permission_name)
372
372
373 @classmethod
373 @classmethod
374 def get_by_key(cls, key):
374 def get_by_key(cls, key):
375 return Session.query(cls).filter(cls.permission_name == key).scalar()
375 return Session.query(cls).filter(cls.permission_name == key).scalar()
376
376
377 class RepoToPerm(Base):
377 class RepoToPerm(Base):
378 __tablename__ = 'repo_to_perm'
378 __tablename__ = 'repo_to_perm'
379 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
379 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'extend_existing':True})
380 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
380 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
381 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
381 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
382 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
382 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
383 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
383 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
384
384
385 user = relationship('User')
385 user = relationship('User')
386 permission = relationship('Permission')
386 permission = relationship('Permission')
387 repository = relationship('Repository')
387 repository = relationship('Repository')
388
388
389 class UserToPerm(Base):
389 class UserToPerm(Base):
390 __tablename__ = 'user_to_perm'
390 __tablename__ = 'user_to_perm'
391 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
391 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'extend_existing':True})
392 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
392 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
393 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
393 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
394 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
394 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
395
395
396 user = relationship('User')
396 user = relationship('User')
397 permission = relationship('Permission')
397 permission = relationship('Permission')
398
398
399 @classmethod
399 @classmethod
400 def has_perm(cls, user_id, perm):
400 def has_perm(cls, user_id, perm):
401 if not isinstance(perm, Permission):
401 if not isinstance(perm, Permission):
402 raise Exception('perm needs to be an instance of Permission class')
402 raise Exception('perm needs to be an instance of Permission class')
403
403
404 return Session.query(cls).filter(cls.user_id == user_id)\
404 return Session.query(cls).filter(cls.user_id == user_id)\
405 .filter(cls.permission == perm).scalar() is not None
405 .filter(cls.permission == perm).scalar() is not None
406
406
407 @classmethod
407 @classmethod
408 def grant_perm(cls, user_id, perm):
408 def grant_perm(cls, user_id, perm):
409 if not isinstance(perm, Permission):
409 if not isinstance(perm, Permission):
410 raise Exception('perm needs to be an instance of Permission class')
410 raise Exception('perm needs to be an instance of Permission class')
411
411
412 new = cls()
412 new = cls()
413 new.user_id = user_id
413 new.user_id = user_id
414 new.permission = perm
414 new.permission = perm
415 try:
415 try:
416 Session.add(new)
416 Session.add(new)
417 Session.commit()
417 Session.commit()
418 except:
418 except:
419 Session.rollback()
419 Session.rollback()
420
420
421
421
422 @classmethod
422 @classmethod
423 def revoke_perm(cls, user_id, perm):
423 def revoke_perm(cls, user_id, perm):
424 if not isinstance(perm, Permission):
424 if not isinstance(perm, Permission):
425 raise Exception('perm needs to be an instance of Permission class')
425 raise Exception('perm needs to be an instance of Permission class')
426
426
427 try:
427 try:
428 Session.query(cls).filter(cls.user_id == user_id)\
428 Session.query(cls).filter(cls.user_id == user_id)\
429 .filter(cls.permission == perm).delete()
429 .filter(cls.permission == perm).delete()
430 Session.commit()
430 Session.commit()
431 except:
431 except:
432 Session.rollback()
432 Session.rollback()
433
433
434 class UsersGroupRepoToPerm(Base):
434 class UsersGroupRepoToPerm(Base):
435 __tablename__ = 'users_group_repo_to_perm'
435 __tablename__ = 'users_group_repo_to_perm'
436 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
436 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'extend_existing':True})
437 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
437 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
438 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
438 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
439 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
439 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
440 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
440 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
441
441
442 users_group = relationship('UsersGroup')
442 users_group = relationship('UsersGroup')
443 permission = relationship('Permission')
443 permission = relationship('Permission')
444 repository = relationship('Repository')
444 repository = relationship('Repository')
445
445
446
446
447 class UsersGroupToPerm(Base):
447 class UsersGroupToPerm(Base):
448 __tablename__ = 'users_group_to_perm'
448 __tablename__ = 'users_group_to_perm'
449 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
449 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
450 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
450 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
451 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
451 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
452
452
453 users_group = relationship('UsersGroup')
453 users_group = relationship('UsersGroup')
454 permission = relationship('Permission')
454 permission = relationship('Permission')
455
455
456
456
457 @classmethod
457 @classmethod
458 def has_perm(cls, users_group_id, perm):
458 def has_perm(cls, users_group_id, perm):
459 if not isinstance(perm, Permission):
459 if not isinstance(perm, Permission):
460 raise Exception('perm needs to be an instance of Permission class')
460 raise Exception('perm needs to be an instance of Permission class')
461
461
462 return Session.query(cls).filter(cls.users_group_id ==
462 return Session.query(cls).filter(cls.users_group_id ==
463 users_group_id)\
463 users_group_id)\
464 .filter(cls.permission == perm)\
464 .filter(cls.permission == perm)\
465 .scalar() is not None
465 .scalar() is not None
466
466
467 @classmethod
467 @classmethod
468 def grant_perm(cls, users_group_id, perm):
468 def grant_perm(cls, users_group_id, perm):
469 if not isinstance(perm, Permission):
469 if not isinstance(perm, Permission):
470 raise Exception('perm needs to be an instance of Permission class')
470 raise Exception('perm needs to be an instance of Permission class')
471
471
472 new = cls()
472 new = cls()
473 new.users_group_id = users_group_id
473 new.users_group_id = users_group_id
474 new.permission = perm
474 new.permission = perm
475 try:
475 try:
476 Session.add(new)
476 Session.add(new)
477 Session.commit()
477 Session.commit()
478 except:
478 except:
479 Session.rollback()
479 Session.rollback()
480
480
481
481
482 @classmethod
482 @classmethod
483 def revoke_perm(cls, users_group_id, perm):
483 def revoke_perm(cls, users_group_id, perm):
484 if not isinstance(perm, Permission):
484 if not isinstance(perm, Permission):
485 raise Exception('perm needs to be an instance of Permission class')
485 raise Exception('perm needs to be an instance of Permission class')
486
486
487 try:
487 try:
488 Session.query(cls).filter(cls.users_group_id == users_group_id)\
488 Session.query(cls).filter(cls.users_group_id == users_group_id)\
489 .filter(cls.permission == perm).delete()
489 .filter(cls.permission == perm).delete()
490 Session.commit()
490 Session.commit()
491 except:
491 except:
492 Session.rollback()
492 Session.rollback()
493
493
494
494
495 class GroupToPerm(Base):
495 class GroupToPerm(Base):
496 __tablename__ = 'group_to_perm'
496 __tablename__ = 'group_to_perm'
497 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
497 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'extend_existing':True})
498
498
499 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
499 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
500 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
500 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
501 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
501 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
502 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
502 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
503
503
504 user = relationship('User')
504 user = relationship('User')
505 permission = relationship('Permission')
505 permission = relationship('Permission')
506 group = relationship('Group')
506 group = relationship('Group')
507
507
508 class Statistics(Base):
508 class Statistics(Base):
509 __tablename__ = 'statistics'
509 __tablename__ = 'statistics'
510 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
510 __table_args__ = (UniqueConstraint('repository_id'), {'extend_existing':True})
511 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
511 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
512 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
512 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
513 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
513 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
514 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
514 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
515 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
515 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
516 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
516 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
517
517
518 repository = relationship('Repository', single_parent=True)
518 repository = relationship('Repository', single_parent=True)
519
519
520 class UserFollowing(Base):
520 class UserFollowing(Base):
521 __tablename__ = 'user_followings'
521 __tablename__ = 'user_followings'
522 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
522 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
523 UniqueConstraint('user_id', 'follows_user_id')
523 UniqueConstraint('user_id', 'follows_user_id')
524 , {'useexisting':True})
524 , {'extend_existing':True})
525
525
526 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
526 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
527 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
527 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
528 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
528 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
529 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
529 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
530 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
530 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
531
531
532 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
532 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
533
533
534 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
534 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
535 follows_repository = relationship('Repository', order_by='Repository.repo_name')
535 follows_repository = relationship('Repository', order_by='Repository.repo_name')
536
536
537
537
538
538
539 @classmethod
539 @classmethod
540 def get_repo_followers(cls, repo_id):
540 def get_repo_followers(cls, repo_id):
541 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
541 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
542
542
543 class CacheInvalidation(Base):
543 class CacheInvalidation(Base):
544 __tablename__ = 'cache_invalidation'
544 __tablename__ = 'cache_invalidation'
545 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
545 __table_args__ = (UniqueConstraint('cache_key'), {'extend_existing':True})
546 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
546 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
547 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
547 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
548 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
548 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
549 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
549 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
550
550
551
551
552 def __init__(self, cache_key, cache_args=''):
552 def __init__(self, cache_key, cache_args=''):
553 self.cache_key = cache_key
553 self.cache_key = cache_key
554 self.cache_args = cache_args
554 self.cache_args = cache_args
555 self.cache_active = False
555 self.cache_active = False
556
556
557 def __repr__(self):
557 def __repr__(self):
558 return "<%s('%s:%s')>" % (self.__class__.__name__,
558 return "<%s('%s:%s')>" % (self.__class__.__name__,
559 self.cache_id, self.cache_key)
559 self.cache_id, self.cache_key)
560
560
561 class DbMigrateVersion(Base):
561 class DbMigrateVersion(Base):
562 __tablename__ = 'db_migrate_version'
562 __tablename__ = 'db_migrate_version'
563 __table_args__ = {'useexisting':True}
563 __table_args__ = {'extend_existing':True}
564 repository_id = Column('repository_id', String(250), primary_key=True)
564 repository_id = Column('repository_id', String(250), primary_key=True)
565 repository_path = Column('repository_path', Text)
565 repository_path = Column('repository_path', Text)
566 version = Column('version', Integer)
566 version = Column('version', Integer)
@@ -1,117 +1,117 b''
1 import sys
1 import sys
2 from rhodecode import get_version
2 from rhodecode import get_version
3 from rhodecode import __platform__
3 from rhodecode import __platform__
4 from rhodecode import __license__
4 from rhodecode import __license__
5 from rhodecode import PLATFORM_OTHERS
5 from rhodecode import PLATFORM_OTHERS
6
6
7 py_version = sys.version_info
7 py_version = sys.version_info
8
8
9 if py_version < (2, 5):
9 if py_version < (2, 5):
10 raise Exception('RhodeCode requires python 2.5 or later')
10 raise Exception('RhodeCode requires python 2.5 or later')
11
11
12 requirements = [
12 requirements = [
13 "Pylons==1.0.0",
13 "Pylons==1.0.0",
14 "WebHelpers>=1.2",
14 "WebHelpers>=1.2",
15 "SQLAlchemy>=0.6.6",
15 "SQLAlchemy>=0.7.0",
16 "Mako>=0.4.0",
16 "Mako>=0.4.0",
17 "vcs>=0.2.1",
17 "vcs>=0.2.1",
18 "pygments>=1.4",
18 "pygments>=1.4",
19 "mercurial>=1.8.1",
19 "mercurial>=1.8.1",
20 "whoosh>=1.8.0",
20 "whoosh>=1.8.4",
21 "celery>=2.2.5",
21 "celery>=2.2.5",
22 "babel",
22 "babel",
23 "python-dateutil>=1.5.0,<2.0.0",
23 "python-dateutil>=1.5.0,<2.0.0",
24 "dulwich>=0.7.1"
24 "dulwich>=0.7.1"
25 ]
25 ]
26
26
27 classifiers = ['Development Status :: 4 - Beta',
27 classifiers = ['Development Status :: 4 - Beta',
28 'Environment :: Web Environment',
28 'Environment :: Web Environment',
29 'Framework :: Pylons',
29 'Framework :: Pylons',
30 'Intended Audience :: Developers',
30 'Intended Audience :: Developers',
31 'Operating System :: OS Independent',
31 'Operating System :: OS Independent',
32 'Programming Language :: Python',
32 'Programming Language :: Python',
33 'Programming Language :: Python :: 2.5',
33 'Programming Language :: Python :: 2.5',
34 'Programming Language :: Python :: 2.6',
34 'Programming Language :: Python :: 2.6',
35 'Programming Language :: Python :: 2.7', ]
35 'Programming Language :: Python :: 2.7', ]
36
36
37 if py_version < (2, 6):
37 if py_version < (2, 6):
38 requirements.append("simplejson")
38 requirements.append("simplejson")
39 requirements.append("pysqlite")
39 requirements.append("pysqlite")
40
40
41 if __platform__ in PLATFORM_OTHERS:
41 if __platform__ in PLATFORM_OTHERS:
42 requirements.append("py-bcrypt")
42 requirements.append("py-bcrypt")
43
43
44
44
45 #additional files from project that goes somewhere in the filesystem
45 #additional files from project that goes somewhere in the filesystem
46 #relative to sys.prefix
46 #relative to sys.prefix
47 data_files = []
47 data_files = []
48
48
49 #additional files that goes into package itself
49 #additional files that goes into package itself
50 package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
50 package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], }
51
51
52 description = ('Mercurial repository browser/management with '
52 description = ('Mercurial repository browser/management with '
53 'build in push/pull server and full text search')
53 'build in push/pull server and full text search')
54 keywords = ' '.join(['rhodecode', 'rhodiumcode', 'mercurial', 'git',
54 keywords = ' '.join(['rhodecode', 'rhodiumcode', 'mercurial', 'git',
55 'repository management', 'hgweb replacement'
55 'repository management', 'hgweb replacement'
56 'hgwebdir', 'gitweb replacement', 'serving hgweb', ])
56 'hgwebdir', 'gitweb replacement', 'serving hgweb', ])
57 #long description
57 #long description
58 try:
58 try:
59 readme_file = 'README.rst'
59 readme_file = 'README.rst'
60 changelog_file = 'docs/changelog.rst'
60 changelog_file = 'docs/changelog.rst'
61 long_description = open(readme_file).read() + '\n\n' + \
61 long_description = open(readme_file).read() + '\n\n' + \
62 open(changelog_file).read()
62 open(changelog_file).read()
63
63
64 except IOError, err:
64 except IOError, err:
65 sys.stderr.write("[WARNING] Cannot find file specified as "
65 sys.stderr.write("[WARNING] Cannot find file specified as "
66 "long_description (%s)\n or changelog (%s) skipping that file" \
66 "long_description (%s)\n or changelog (%s) skipping that file" \
67 % (readme_file, changelog_file))
67 % (readme_file, changelog_file))
68 long_description = description
68 long_description = description
69
69
70
70
71 try:
71 try:
72 from setuptools import setup, find_packages
72 from setuptools import setup, find_packages
73 except ImportError:
73 except ImportError:
74 from ez_setup import use_setuptools
74 from ez_setup import use_setuptools
75 use_setuptools()
75 use_setuptools()
76 from setuptools import setup, find_packages
76 from setuptools import setup, find_packages
77 #packages
77 #packages
78 packages = find_packages(exclude=['ez_setup'])
78 packages = find_packages(exclude=['ez_setup'])
79
79
80 setup(
80 setup(
81 name='RhodeCode',
81 name='RhodeCode',
82 version=get_version(),
82 version=get_version(),
83 description=description,
83 description=description,
84 long_description=long_description,
84 long_description=long_description,
85 keywords=keywords,
85 keywords=keywords,
86 license=__license__,
86 license=__license__,
87 author='Marcin Kuzminski',
87 author='Marcin Kuzminski',
88 author_email='marcin@python-works.com',
88 author_email='marcin@python-works.com',
89 url='http://rhodecode.org',
89 url='http://rhodecode.org',
90 install_requires=requirements,
90 install_requires=requirements,
91 classifiers=classifiers,
91 classifiers=classifiers,
92 setup_requires=["PasteScript>=1.6.3"],
92 setup_requires=["PasteScript>=1.6.3"],
93 data_files=data_files,
93 data_files=data_files,
94 packages=packages,
94 packages=packages,
95 include_package_data=True,
95 include_package_data=True,
96 test_suite='nose.collector',
96 test_suite='nose.collector',
97 package_data=package_data,
97 package_data=package_data,
98 message_extractors={'rhodecode': [
98 message_extractors={'rhodecode': [
99 ('**.py', 'python', None),
99 ('**.py', 'python', None),
100 ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
100 ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}),
101 ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}),
101 ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}),
102 ('public/**', 'ignore', None)]},
102 ('public/**', 'ignore', None)]},
103 zip_safe=False,
103 zip_safe=False,
104 paster_plugins=['PasteScript', 'Pylons'],
104 paster_plugins=['PasteScript', 'Pylons'],
105 entry_points="""
105 entry_points="""
106 [paste.app_factory]
106 [paste.app_factory]
107 main = rhodecode.config.middleware:make_app
107 main = rhodecode.config.middleware:make_app
108
108
109 [paste.app_install]
109 [paste.app_install]
110 main = pylons.util:PylonsInstaller
110 main = pylons.util:PylonsInstaller
111
111
112 [paste.global_paster_command]
112 [paste.global_paster_command]
113 make-index = rhodecode.lib.indexers:MakeIndex
113 make-index = rhodecode.lib.indexers:MakeIndex
114 upgrade-db = rhodecode.lib.dbmigrate:UpgradeDb
114 upgrade-db = rhodecode.lib.dbmigrate:UpgradeDb
115 celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand
115 celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand
116 """,
116 """,
117 )
117 )
General Comments 0
You need to be logged in to leave comments. Login now